• mapstruct实体转换 转换成不同类型


    开发中,我们经常需要将PO转DTO、DTO转PO等一些实体间的转换。比较出名的有BeanUtil 和ModelMapper等,它们使用简单,但是在稍显复杂的业务场景下力不从心。MapStruct这个插件可以用来处理domin实体类与model类的属性映射,可配置性强。只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。MapStruct官网地址: MapStruct – Java bean mappings, the easy way!

    引入依赖

        
          org.mapstruct
          mapstruct-jdk8
          1.1.0.Final
        

    需求

    我们假设有学生student 类 需要转换成 用户 user 类,将学生信息存入用户信息库

    此时Student 类内容如下:

    @Data
    public class Student {
      private Integer id;
      private String name;
      private Integer age;
      private String sex;
      //setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 
      }

    此时User 类内容如下:

    @Data
    public class User {
      private Integer id;
      private String name;
      private Integer age;
      private String sex;
      //setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 
     }

    转换model

    此时 Student 和 User 的属性名字都相同那么转换接口就是

    import org.mapstruct.Mapper;
    @Mapper(componentModel = "spring")
    public interface UserMapping {
      /**
       * Student 转化为 User
       * @param Student
       * @return
       */
       User studentToUser(Student student);
    }

    程序运行前要先编译 mvn clean compile , 从而mapstruct框架生成UserMappingImpl 实现类。

    转换model 属性不匹配

    如果 User 和 Student 的属性名不对应例如:

    此时Student 类内容如下:

    @Data
    public class Student {
      private Integer id;
      private String sname;
      private Integer age;
      private String sex;
      //setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 
      }

    此时User 类内容如下:

    @Data
    public class User {
      private Integer id;
      private String uname;
      private Integer age;
      private String sex;
      //setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 
     }

    那么转换接口为

    import org.mapstruct.Mapper;
    import org.mapstruct.Mapping;
    import org.mapstruct.Mappings;
    @Mapper(componentModel = "spring")
    public interface UserMapping {
      /**
       * Student 转化为 User
       * @param Student
       * @return
       */
       @Mappings({
          @Mapping(target = "uname", source = "sname")
         // 多个属性不对应可以用 "," 隔开编写多个@Mapping
         // ,@Mapping(target = "uname", source = "sname")
      })
       User studentToUser(Student student);
    }

    转换model 属性类型不匹配

    比如说user 类的sex字段类型改为boolean

    此时User 类内容如下:

    @Data
    public class User {
      private Integer id;
      private String uname;
      private Integer age;
      private boolean sex;
      //setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 
     }

    这个转换需求有点变态,所以 需要我门自己写个转换类

    @Slf4j
    @Component
    public class UserTransform {
      public String booleanToString(boolean value){
        if(value){
          return "男";
        }
        return "女";
      }
      public boolean strToBoolean(String str){
        if ("男".equals(str)) {
          return true;
        }
        return false;
      }
    }

    那么转换接口为(使用 UserTransform.class 类)

    import org.mapstruct.Mapper;
    import org.mapstruct.Mapping;
    import org.mapstruct.Mappings;
    @Mapper(componentModel = "spring",uses = UserTransform.class)
    public interface UserMapping {
      /**
       * Student 转化为 User
       * @param Student
       * @return
       */
       @Mappings({
          @Mapping(target = "uname", source = "sname")
         // 多个属性不对应可以用 "," 隔开编写多个@Mapping
         // ,@Mapping(target = "uname", source = "sname")
      })
       User studentToUser(Student student);
    }

    转换list

    当user 和 student 都是集合形式list 时应当如下转换

    转化 List<> 集合时必须有 实体转化,因为在实现中,List 转换是 for循环调用 实体转化的。所以当属性名不对应时,应该在 实体转化进行 @Mappings 的属性名映射配置,然后list的转换也会继承这和属性的映射。

    例如 属性名相同

    import org.mapstruct.Mapper;
    @Mapper(componentModel = "spring")
    public interface UserMapping {
      /**
       * Student 转化为 User
       * @param Student
       * @return
       */
       User studentToUser(Student student);
       /**
       * Students 转化为 Users
       * @param Students
       * @return
       */
       List studentsToUsers(List students);

    属性名不同:

    import org.mapstruct.Mapper;
    import org.mapstruct.Mapping;
    import org.mapstruct.Mappings;
    @Mapper(componentModel = "spring")
    public interface UserMapping {
      /**
       * Student 转化为 User
       * @param Student
       * @return
       */
       @Mappings({
          @Mapping(target = "uname", source = "sname")
         // 多个属性不对应可以用 "," 隔开编写多个@Mapping
         // ,@Mapping(target = "uname", source = "sname")
      })
       User studentToUser(Student student);
      /**
       * 此时 studentsToUsers 的实现为循环调用 studentToUser 并继承了 studentToUser 的属性映射
       * Students 转化为 Users
       * @param Students
       * @return
       */
       List studentsToUsers(List students);
    }

    展示自动生成的 UserMappingImpl 实现(此类为 执行 mvn clean compile 后自动生成)

    @Component
    public class UserMappingImpl implements UserMapping {
      @Override
      public User studentToUser(student student) {
        if ( student == null ) {
          return null;
        }
        User user = new User();
        User.setId(student.getId() );
        User.setName(student.getName() );
        // 如果配置了属性映射则为
        //User.setUname(student.getSname() );
        User.setSex(student.getSex() );
        User.setAge(student.getAge() );
        return user;
      }
      @Override
      public List studentsToUsers(List students) {
        if ( students == null ) {
          return null;
        }
        List list = new ArrayList();
        for ( student student : students ) {
          list.add( studentToUser( student ) );
        }
        return list;
      }
    }
  • 相关阅读:
    Qt编写物联网管理平台(支持win/linux/mac/嵌入式linux/modbus等)
    【面试题精讲】Java移位运算符
    Panda3d 动画序列
    Ghidra反编译报错Can‘t read language spec ***/***/***/mips32be.sla
    同步锁的分类
    C++~从编译链接的过程看为什么C++支持重载?externC有什么用?
    ​GOPS演讲 | 如何构建现代运营与支持体系,实现团队的高效协同
    ThinkPHP和uniapp开发的CRM售后管理系统(客户、合同、工单、任务、报价、产品、库存、出纳、收费)
    这款开源神器,让聚类算法从此变得简单易用
    使用微信开发者工具模拟微信小程序定位
  • 原文地址:https://blog.csdn.net/loliDapao/article/details/127790645