Java 对象属性映射转换器 mapStruct ,PO转VO或VO转DTO等

在项目中,时常有DTO、VO、BO等转换问题时候,我们会使用Apache或者Spring的BeanUtils来做copy。他们使用的原理都是反射,而且是浅拷贝性能不高。

场景 耗时(调用100万次) 原理
get/set 20ms 直接调用
MapStruct 20ms 接口映射注入(简洁方便)
BeanCopiers 20ms 基于 cglib,修改字节码
BeanUtils 12000ms 反射
PropertyUtils 4000ms 反射

MapStruct 性能强悍,时间短,通过生成冗长且容易出错的代码来节省时间。在配置方法的约定之后,MapStruct使用了合理的默认值,但在配置或实现特殊行为时将不再适用。

“阿里巴巴编码规范”也有提尽量避免使用BeanUtils工具
在这里插入图片描述
使用get/set代码臃肿不够简洁,BeanUtils 、PropertyUtils 性能不够时间长,而BeanCopiers 不过频繁的create太占用资源,降低服务器性能,所以推荐使用MapStruct 来进行对象代码装换。

使用MapStruct

官方查看官网: https://mapstruct.org/
#文档讲解非常详细
使用文档:https://mapstruct.org/documentation/stable/reference/html/

引入依赖

	>
        >1.3.1.Final>
    >

 	>
		<!--lombok 辅助工具-->
        
            org.projectlombok
            lombok
            1.18.12
            provided
        
        
            org.mapstruct
            mapstruct
            ${mapstruct.version}
        
        
            org.mapstruct
            mapstruct-jdk8
            ${mapstruct.version}
        
        
            org.mapstruct
            mapstruct-processor
            ${mapstruct.version}
        
	>

准备几个POJO对象用来相互装换

//课程实体
@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class Course {
     
    private String courseName;
    private int sortNo;
    private long id;
}
//学生实体
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {
     
    private String name;
    private int age;
    private GenderEnum gender;
    private Double height;
    private LocalDate birthday;

}
//学生响应VO
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StudentVO {
     
    private String name;
    private int age;
    private String gender;
    private Double height;
    private String birthday;
    private String course;
}

//性别枚举测试装换
@Getter
@AllArgsConstructor
public enum GenderEnum {
     

    Male("1", "男"),
    Female("0", "女");

    private String code;
    private String name;

}

定义一个装换映射器

import org.mapstruct.MapMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import tuan.entity.Course;
import tuan.entity.Student;
import tuan.entity.StudentVO;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * POJO映射装换
 * @author DuanLinpeng
 * @date 2021/01/09 22:12
 **/
@Mapper
public interface ConverMapper {
     

    ConverMapper INSTANCE = Mappers.getMapper(ConverMapper.class);

    @Mapping(source = "gender.name", target = "gender")
    @Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd")
    StudentVO student2StudentVO(Student student);

    /**
     *  学生和科目拼接
     * @author DuanLinpeng
     * @date 2021/01/09 23:33
     * @param student
     * @param course
     * @return tuan.entity.StudentVO
     */
    @Mapping(source = "student.gender.name", target = "gender")
    @Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd ")
    @Mapping(source = "course.courseName", target = "course")
    @Mapping(target = "name", source = "student.name", defaultValue = "张三")
    StudentVO studentAndCourse2StudentVO(Student student, Course course);

    /**
     *  集合装换成集合
     * @author DuanLinpeng
     * @date 2021/01/09 23:25
     * @param studentList
     * @return java.util.List
     */
    List<StudentVO> students2StudentVOs(List<Student> studentList);

    /**
     *  Map 装换Map
     * @author DuanLinpeng
     * @date 2021/01/10 13:11
     * @param source
     * @return java.util.Map
     */
    @MapMapping(valueDateFormat = "dd-MM-yyyy")
    Map<String, String> LocalDateMapToStringStringMap(Map<Long, LocalDate> source);
    /**
     *  Set 装换Set<指定类型>
     * @author DuanLinpeng
     * @date 2021/01/10 13:17
     * @param integers
     * @return java.util.Set
     */
    Set<String> integerSetToStringSet(Set<Integer> integers);

}

测试启动类

public static void main(String[] args) {
     
        //DTO对象装换VO对象
        Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(LocalDate.now()).build();
        System.out.println(student);
        //这行代码便是实际要用的代码
        StudentVO studentVO = ConverMapper.INSTANCE.student2StudentVO(student);
        System.out.println(studentVO);

        //List DTO对象装换List VO对象
        Student studentlist = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(LocalDate.now()).build();
        List<Student> list = new ArrayList<>();
        list.add(studentlist);
        List<StudentVO> result = ConverMapper.INSTANCE.students2StudentVOs(list);
        System.out.println("List 》》"+result);


        //*二个对象拼接到一起
        Student studentSplice = Student.builder().name(null).age(6).gender(GenderEnum.Male).height(121.1).birthday(LocalDate.now()).build();
        Course courseSplice = Course.builder().id(1L).courseName("语文").build();
        StudentVO studentSpliceVO = ConverMapper.INSTANCE.studentAndCourse2StudentVO(studentSplice, courseSplice);
        System.out.println("Student And Course 》》"+studentSpliceVO);

        //Map值Object 类型装换出自定Map类型
        Map<Long, LocalDate> map = new HashMap<>();
        map.put(1L,LocalDate.now());
        Map<String, String> mapStr = ConverMapper.INSTANCE.LocalDateMapToStringStringMap(map);
        System.out.println("Long And LocalDate 》》"+mapStr);

        //Set 类型装换出自定Set类型
        Set<Integer> set = new HashSet<>();
        set.addAll(Arrays.asList(1,2,3,4,5));
        Set<String> stringSet = ConverMapper.INSTANCE.integerSetToStringSet(set);
        System.out.println("Set To Set 》》"+stringSet);

    }
 
  

运行结果:

Student(name=小明, age=6, gender=Male, height=121.1, birthday=2021-01-10)
StudentVO(name=小明, age=6, gender=, height=121.1, birthday=2021-01-10, course=null)
List 》》[StudentVO(name=小明, age=6, gender=, height=121.1, birthday=2021-01-10, course=null)]
Student And Course 》》StudentVO(name=张三, age=6, gender=, height=121.1, birthday=2021-01-10 , course=语文)
Long And LocalDate 》》{
     1=10-01-2021}
Set<Integer> To Set<String> 》》[1, 2, 3, 4, 5]

还有很多用法请看官方文档:https://mapstruct.org/documentation/stable/reference/html/

你可能感兴趣的:(Java,日常开发,java,数据类型)