MapStruct使用和原理分析

女爷i 2021-09-25 01:26 470阅读 0赞

在代码开发中,经常会遇到不同实体类之间的字段copy,以前经常用到的有通过set赋值或者apache、spring的BeanUtils.copyProperties(),原生的set赋值随便速度比较快,但是当字段多的时候,就显得比较麻烦了,每个都要自己手动set一下值,而apache、spring的BeanUtils.copyProperties()可以解决这种字段比较多的情况,但是这种方式有个弊端,就是,字段的类型和名称都必须一样才可以,否则copy时会被忽略掉,还有个关键的问题就是apache的BeanUtils.copyProperties()效率比较低,spring的BeanUtils.copyProperties()效率还可以。直到接触了一种新的方式,使用MapStruct方式。

加入MapStruct的依赖jar包

  1. <properties>
  2. <mapstruct.version>1.2.0.Final</mapstruct.version>
  3. </properties>
  4. <dependency>
  5. <groupId>org.mapstruct</groupId>
  6. <artifactId>mapstruct-jdk8</artifactId>
  7. <version>${mapstruct.version}</version>
  8. </dependency>
  9. <dependency>
  10. <groupId>org.mapstruct</groupId>
  11. <artifactId>mapstruct-processor</artifactId>
  12. <version>${mapstruct.version}</version>
  13. </dependency>

创建实体类User

  1. public class User {
  2. private Integer id;
  3. private String userName;
  4. private String desc;
  5. private Integer age;
  6. private Double salary;
  7. public Integer getId() {
  8. return id;
  9. }
  10. public void setId(Integer id) {
  11. this.id = id;
  12. }
  13. public String getUserName() {
  14. return userName;
  15. }
  16. public void setUserName(String userName) {
  17. this.userName = userName;
  18. }
  19. public String getDesc() {
  20. return desc;
  21. }
  22. public void setDesc(String desc) {
  23. this.desc = desc;
  24. }
  25. public Integer getAge() {
  26. return age;
  27. }
  28. public void setAge(Integer age) {
  29. this.age = age;
  30. }
  31. public Double getSalary() {
  32. return salary;
  33. }
  34. public void setSalary(Double salary) {
  35. this.salary = salary;
  36. }
  37. }

创建UserDTO类

  1. public class UserDTO {
  2. private Integer id;
  3. private String userName;
  4. private Date createDate;
  5. private String remark;
  6. public Integer getId() {
  7. return id;
  8. }
  9. public void setId(Integer id) {
  10. this.id = id;
  11. }
  12. public String getUserName() {
  13. return userName;
  14. }
  15. public void setUserName(String userName) {
  16. this.userName = userName;
  17. }
  18. public Date getCreateDate() {
  19. return createDate;
  20. }
  21. public void setCreateDate(Date createDate) {
  22. this.createDate = createDate;
  23. }
  24. public String getRemark() {
  25. return remark;
  26. }
  27. public void setRemark(String remark) {
  28. this.remark = remark;
  29. }
  30. public UserDTO() {
  31. }
  32. @Override
  33. public String toString() {
  34. return "UserDTO{" +
  35. "id=" + id +
  36. ", userName='" + userName + '\'' +
  37. ", createDate=" + createDate +
  38. ", remark='" + remark + '\'' +
  39. '}';
  40. }

创建接口UserMapStruct

  1. import org.mapstruct.MapMapping;
  2. import org.mapstruct.Mapper;
  3. import org.mapstruct.Mapping;
  4. import org.mapstruct.Mappings;
  5. import org.mapstruct.factory.Mappers;
  6. @Mapper
  7. public interface UserMapStruct {
  8. UserMapStruct INSTANCE = Mappers.getMapper(UserMapStruct.class);
  9. @Mappings({
  10. @Mapping(source = "desc",target = "remark")
  11. })
  12. public UserDTO userToDto(User user);
  13. }

代码测试

  1. public class TestUserMapStruct {
  2. public static void main(String[] args) {
  3. User user = new User();
  4. user.setId(1000);
  5. user.setAge(21);
  6. user.setDesc("测试复制工具");
  7. user.setSalary(400.44);
  8. user.setUserName("张三");
  9. UserDTO userDTO = UserMapStruct.INSTANCE.userToDto(user);
  10. System.out.println(userDTO.toString());
  11. }
  12. }

输出结果
20201225212851116.png

我们可以看到字段的值已经赋值到UserDTO上了。

MapStruct原理:

MapStruct是基于JSR 269的Java注解处理器,因此可以在命令行构建中使用(javac、Ant、Maven等等),也可以在IDE内使用。包括以下几个组件

org.mapstruct:mapstruct:包含了必要的注解,例如@Mapping;在Java 8或更高版本中,使用
org.mapstruct:mapstruct-jdk8,而不是利用Java 8中引入的语言进行改进。
org.mapstruct:mapstruct-processor:包含生成映射器实现的注解处理器

在编译过程中会根据自己的Mapper接口生成对应的实现类,比如上面定义的UserMapStruct类

发表评论

表情:
评论列表 (有 0 条评论,470人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Mapstruct原理

    一、Mapstruct简介        MapStruct是用于生成类型安全的bean映射类的Java注解处理器。        你所要做的就是定义一个映射器接口,