举个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
@Data @Builder @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; private String email; private String username; private String password; private Integer gender; private Date birthday; }
@Data public class UserRegisterReq { private String username; private String password; private String confirmPassword; private String email; }
|
UserRegisterReq是用户注册时,Controller层的请求入参
User是用户实体
在执行注册时,我们需要将UserRegisterReq转换成User对象,再存储到数据库。此时,我们往往会编写类似如下的代码:
1 2 3 4 5 6 7 8 9
|
@PostMapping("/users/reg") public void reg(@RequestBody UserRegisterReq userRegisterReq) { User user = new User(); user.setEmail(userRegisterReq.getEmail()); user.setPassword(userRegisterReq.getPassword()); user.setUsername(userRegisterReq.getUsername()); }
|
如上的代码虽然可行,但是如果类里面的field非常多,那么就会比较麻烦——我们写了一堆代码,只不过是为了实现对象的转换而已。
https://plugins.jetbrains.com/plugin/9360-generateallsetter
GitHub:
https://github.com/gejun123456/intellij-generateAllSetMethod
演示如下图:
只需安装插件,然后按Alt + Enter(macOS则是Option + Enter),即可自动生成对象转换代码。
dozer
1.9K stars
orika
1.2K stars
mapstruct
5K stars
cglib
4.3K stars
commons-beanutils
0.2K stars
大量反射,主要基于Field.set(obj, obj)为field赋值
基于javassist生成对象映射字节码,并加载生成的字节码文件
基于JSR269,在在编译期生成对象映射代码
基于ASM的MethodVisitor为field赋值
基于Spring反射工具类
虽然选项很多,
但笔者目前只建议大家使用MapStruct
。
MapStruct优势:
编译器生成Getter/Setter,无运行期性能损耗,性能强劲
基于JSR269,配置灵活
基于Getter/Setter,和自己手写Getter/Setter没有区别,搜索字段引用等较方便
由于配置灵活,所以上手成本比其他组件稍微高一点点
https://mapstruct.org/documentation/ide-support/
,配置你的IDE
在项目中添加如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
<properties> <org.mapstruct.version>1.4.2.Final</org.mapstruct.version> </properties> ... <dependencies> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${org.mapstruct.version}</version> </dependency> </dependencies> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${org.mapstruct.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
|
如果你的项目使用了Lombok,或使用了spring-boot-configuration-processor,则使用类似如下的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
<properties> <org.mapstruct.version>1.4.2.Final</org.mapstruct.version> </properties> ... <dependencies> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${org.mapstruct.version}</version> </dependency> </dependencies> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>8</source> <target>8</target> <encoding>UTF-8</encoding> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${org.mapstruct.version}</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok-mapstruct-binding</artifactId> <version>0.1.0</version> </path> <path> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>2.4.1</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
|
定义接口,代码类似如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
import com.itmuch.gogolive1.domain.User; import com.itmuch.gogolive1.domain.UserRegisterReq; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers;
@Mapper public interface UserConverter {
UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
User toUser(UserRegisterReq req); }
|
1 2 3 4 5 6
|
@PostMapping("/users/reg") public void reg2(@RequestBody UserRegisterReq userRegisterReq) { User user = UserConverter.INSTANCE.toUser(userRegisterReq); }
|
由代码可知,只需如下代码,即可将UserRegisterReq转换User。
1
|
User user = UserConverter.INSTANCE.toUser(userRegisterReq);
|
https://mapstruct.org/documentation/dev/reference/html
查阅。个人经验来说,当转换的对象之间差异较大时,MapStruct的配置也会变得非常复杂,此时代码可读性、复杂性等等都比较高一些。个人不太喜欢折腾MapStruct,所以当遇到复杂情况时,笔者就直接手动实现对象映射了。毕竟,引入工具是帮助我们提效的,如果MapStruct需要大量配置,那意义就不大了。
https://github.com/mapstruct/mapstruct-examples
相关文章