• 高性能实体类转换工具MapStruct 使用教程


    1、什么MapStruct

    ​ 我们开发过程中会遇到很多bean拷贝得过程,最简单粗暴得方法就是set/get方法,当然这也是最愚蠢得方法,代码显得过于冗长和笨重,其次还有框架BeanUtils在使用反射的时候都会影响到性能。虽然我们可以进行反射信息的缓存来提高性能。但是像这种的话,需要类型和名称都一样才会进行映射,有很多时候,由于不同的团队之间使用的名词不一样,还是需要很多的手动 set/get 等功能。

    MapStruct 就解决了这些问题带来的困扰,它是一个生成类型安全,高性能且无依赖的 JavaBean 映射代码的注解处理器(annotation processor)

    • 注解处理器
    • 可以生成 JavaBean 之间那的映射代码
    • 类型安全,高性能,无依赖性

    2、优点分析

    性能高

    这是相对反射来说的,反射需要去读取字节码的内容,花销会比较大。而通过 MapStruct 来生成的代码,其类似于人手写。速度上可以得到保证。

    使用简单

    如果是完全映射的,使用起来肯定没有反射简单。用类似 BeanUtils 这些工具一条语句就搞定了。但是,如果需要进行特殊的匹配(特殊类型转换,多对一转换等),其相对来说也是比较简单的。

    基本上,使用的时候,我们只需要声明一个接口,接口下写对应的方法,就可以使用了。当然,如果有特殊情况,是需要额外处理的。

    代码独立

    生成的代码是对立的,没有运行时的依赖。

    易于 debug

    在我们生成的代码中,我们可以轻易的进行 debug。

    3、如何使用

    pom引入

        
        
            org.mapstruct
            mapstruct
            1.4.2.Final
        
        
            org.mapstruct
            mapstruct-jdk8
            1.4.2.Final
        
        
            org.mapstruct
            mapstruct-processor
            1.4.2.Final
        
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    实体类

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Student implements Serializable {
        /**
         * id
         */
        private Integer id;
        /**
         * 学生姓名
         */
        private String name;
        /**
         * 年龄
         */
        private Integer age;
        /**
         * 性别
         */
        private String sex;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    准备VO类

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class StudentRequestVo {
    
        /**
         * id
         */
        private Integer studentId;
        /**
         * 学生姓名
         */
        private String studentName;
        /**
         * 年龄
         */
        private Integer studentAge;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    定义转换器

    	//这个注解是MapStruct得注解,不是mybatis注解
    	@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
    public interface StudentMapStrut {
    
        @Mappings({
                @Mapping(target = "id",source = "studentId"),
                @Mapping(target = "name",source = "studentName"),
                @Mapping(target = "age",source = "studentAge")
        })
        Student studentConvert(StudentRequestVo studentRequestVo);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    使用

     Student student = studentMapStrut.studentConvert(new StudentRequestVo(1, "张三", 15));
    
    • 1
    List互转
    @Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
    public interface StudentMapStrut {
    
        @Mappings({
                @Mapping(target = "id",source = "studentId"),
                @Mapping(target = "name",source = "studentName"),
                @Mapping(target = "age",source = "studentAge")
        })
        Student studentConvert(StudentRequestVo studentRequestVo);
    
        List studentListConvert(List studentRequestVos);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    多个对象映射一个对象
    //老师学生vo
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class StudentAndTeacher implements Serializable {
        /**
         * id
         */
        private Integer id;
        /**
         * 学生姓名
         */
        private String studentName;
        /**
         * 老师姓名
         */
        private String teacherName;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    //学生vo
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class StudentRequestVo {
    
        /**
         * id
         */
        private Integer studentId;
        /**
         * 学生姓名
         */
        private String studentName;
        /**
         * 年龄
         */
        private Integer studentAge;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    //老师vo
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class TeacherRequestVo {
    
        /**
         * id
         */
        private Integer teacherId;
        /**
         * 学生姓名
         */
        private String teacherName;
        /**
         * 年龄
         */
        private Integer teacherAge;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    映射成一个对象

        @Mappings({
            @Mapping(target = "studentName",source = "studentRequestVo.studentName"),
            @Mapping(target = "teacherName",source = "teacherRequestVo.teacherName")
    })
    StudentAndTeacher studentAndTeacherConvert(StudentRequestVo studentRequestVo,TeacherRequestVo teacherRequestVo);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    自定义转换

    以对象转换为例,我们想把年龄20岁以下的,统一存储为0,20岁以上的统一存储为1.

        @Mappings({
            @Mapping(target = "id",source = "studentId"),
            @Mapping(target = "name",source = "studentName"),
            @Mapping(target = "age",expression = "java(com.example.demo.mapstrut.MapStructUtil.ageConvert(studentRequestVo.getStudentAge()))")
    })
    Student studentConvert(StudentRequestVo studentRequestVo);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    	public class MapStructUtil {
    
        public static Integer ageConvert(Integer studentAge){
            if (studentAge<=20){
                return 0;
            }else {
                return 1;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.总结:
    mapstruct还有很多功能,例如dateFormat 、numberFormat 实现自定义转换,平时使用基本可以参考本文。如需更详细了解可参考官网: https://mapstruct.org/documentation/stable/reference/html/


    关注我的微信公众号
    ​​​​在这里插入图片描述

  • 相关阅读:
    AVR单片机开发2——流水灯及仿真
    五分钟搭建开源ERP:Odoo,并实现公网远程访问
    【蓝桥每日一题]-动态规划 (保姆级教程 篇10)#方格取数
    java spring cloud 企业工程管理系统源码+二次开发+定制化服务
    SpringBoot使用kafka事务-消费者方
    Windows 11 电脑黑屏 + Office软件打不开?
    C# 加解密之AES
    易观分析联合中小银行联盟发布海南数字经济指数,敬请期待!
    Python使用修饰函数判断执行时间
    Matlab论文插图绘制模板第115期—带Latex公式的图
  • 原文地址:https://blog.csdn.net/CharlesYooSky/article/details/126004466