一、MapStruct介绍
这是什么?
MapStruct 是一个代码生成器,它极大地简化了基于约定而不是配置方法的 Java Bean 类型之间映射的实现。
生成的映射代码使用普通方法调用,因此快速、类型安全且易于理解。
为什么?
多层应用程序通常需要在不同的对象模型(例如实体和 DTO)之间进行映射。编写此类映射代码是一项繁琐且容易出错的任务。MapStruct旨在通过尽可能地自动化来简化这项工作。
与其他映射框架相比,MapStruct 在编译时生成 Bean 映射,从而确保高性能,允许快速的开发人员反馈和彻底的错误检查。
如何?
MapStruct是一个注释处理器,它插入到Java编译器中,可以在命令行构建(Maven,Gradle等)以及您首选的IDE中使用。
MapStruct使用合理的默认值,但在配置或实现特殊行为时会偏离您的道路。
官网:MapStruct – Java bean mappings, the easy way!
二、lombok介绍
Lombok是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。官方地址:
https://projectlombok.org/,github地址:https://github.com/rzwitserloot/lombok。
参考资料:史上最全 Lombok Features 注解详解
三、如何简化
1、导入依赖
<properties> <mapstruct.version>1.3.1.Final</mapstruct.version> <lombok.version>1.18.12</lombok.version> </properties> <dependencies> <!-- 引入 mapstruct 依赖 --> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${mapstruct.version}</version> </dependency> <!-- 引入 lombok 依赖 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> <annotationProcessorPaths> <!-- 引入 mapstruct-processor --> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> </path> <!-- 引入 projectlombok --> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
2、使用示例
用户
package com.example.demo; import lombok.*; @Getter @Setter @Builder @ToString @NoArgsConstructor @AllArgsConstructor public class User { /*用户ID*/ private Long id; /*用户名*/ private String username; /*密码*/ private String password; /*电话*/ private String phone; private Work work; }
工作
package com.example.demo; import lombok.*; @Getter @Setter @Builder @ToString @NoArgsConstructor @AllArgsConstructor public class Work { private Long id; private String workName; }
传输需要的DTO
package com.example.demo; import lombok.*; @Getter @Setter @Builder @ToString @NoArgsConstructor @AllArgsConstructor public class UserWorkDTO { /** * 用户id */ private Long userId; /** * 用户名 */ private String name; /** * 岗位名 */ private String workName; }
目标:将如下User和Work赋值给为UserWorkDTO
User(id=1, username=Spinoza, password=null, phone=1312313131, work=null) Work(id=null, workName=码农) UserWorkDTO(userId=1, name=Spinoza, workName=码农)
日常
@Test void contextLoads1() { //新建用户 User user=new User(); user.setId(1L); user.setUsername("Spinoza"); user.setPhone("1312313131"); //新建工作 Work work=new Work(); work.setWorkName("码农"); //给DTO赋值 UserWorkDTO userWorkDTO=new UserWorkDTO(); userWorkDTO.setUserId(user.getId()); userWorkDTO.setName(user.getUsername()); userWorkDTO.setWorkName(work.getWorkName()); System.out.println(userWorkDTO.toString()); }
使用lombok的@Builder简化代码
@Test void contextLoads2() { //新建用户 User user=User.builder().id(1L).username("Spinoza").phone("1312313131").build(); //新建工作 Work work=Work.builder().workName("码农").build(); //给DTO赋值 UserWorkDTO userWorkDTO=UserWorkDTO.builder().userId(user.getId()).name(user.getUsername()).workName(work.getWorkName()).build(); System.out.println(userWorkDTO.toString()); }
使用lombok的@Builder、MapStruct简化代码
package com.example.demo; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; /*定义转换接口*/ @Mapper public interface UserWorkDTOConverter { //获取转换实例 UserWorkDTOConverter INSTANCE = Mappers.getMapper(UserWorkDTOConverter.class); /*定义转换属性映射关系*/ @Mappings({ @Mapping(source = "user.id", target = "userId"), @Mapping(source = "user.username", target = "name"), @Mapping(source = "work.workName", target = "workName") }) UserWorkDTO cover(User user,Work work); }
@Test void contextLoads3() { //新建用户 User user=User.builder().id(1L).username("Spinoza").phone("1312313131").build(); //新建工作 Work work=Work.builder().workName("码农").build(); //给DTO赋值 UserWorkDTO cover = UserWorkDTOConverter.INSTANCE.cover(user, work); System.out.println(cover.toString()); }