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

1、什么MapStruct

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

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

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

2、优点分析

性能高

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

使用简单

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

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

代码独立

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

易于 debug

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

3、如何使用

pom引入

    <!--  mapStruct开始  -->
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.4.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-jdk8</artifactId>
        <version>1.4.2.Final</version>
    </dependency>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>1.4.2.Final</version>
    </dependency>
    <!--  mapStruct结束  -->

实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Serializable {
    /**
     * id
     */
    private Integer id;
    /**
     * 学生姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 性别
     */
    private String sex;
}

准备VO类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentRequestVo {

    /**
     * id
     */
    private Integer studentId;
    /**
     * 学生姓名
     */
    private String studentName;
    /**
     * 年龄
     */
    private Integer studentAge;

}

定义转换器

	//这个注解是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);

}

使用

 Student student = studentMapStrut.studentConvert(new StudentRequestVo(1, "张三", 15));
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<Student> studentListConvert(List<StudentRequestVo> studentRequestVos);

}
多个对象映射一个对象
//老师学生vo
@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentAndTeacher implements Serializable {
    /**
     * id
     */
    private Integer id;
    /**
     * 学生姓名
     */
    private String studentName;
    /**
     * 老师姓名
     */
    private String teacherName;
}

//学生vo
@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentRequestVo {

    /**
     * id
     */
    private Integer studentId;
    /**
     * 学生姓名
     */
    private String studentName;
    /**
     * 年龄
     */
    private Integer studentAge;
}
//老师vo
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TeacherRequestVo {

    /**
     * id
     */
    private Integer teacherId;
    /**
     * 学生姓名
     */
    private String teacherName;
    /**
     * 年龄
     */
    private Integer teacherAge;

}

映射成一个对象

    @Mappings({
        @Mapping(target = "studentName",source = "studentRequestVo.studentName"),
        @Mapping(target = "teacherName",source = "teacherRequestVo.teacherName")
})
StudentAndTeacher studentAndTeacherConvert(StudentRequestVo studentRequestVo,TeacherRequestVo teacherRequestVo);

自定义转换

以对象转换为例,我们想把年龄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);

	public class MapStructUtil {

    public static Integer ageConvert(Integer studentAge){
        if (studentAge<=20){
            return 0;
        }else {
            return 1;
        }
    }
}

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


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

猜你喜欢

转载自blog.csdn.net/CharlesYooSky/article/details/126004466