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

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

场景耗时(调用100万次)原理
get/set20ms直接调用
MapStruct20ms接口映射注入(简洁方便)
BeanCopiers20ms基于 cglib,修改字节码
BeanUtils12000ms反射
PropertyUtils4000ms反射

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

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

使用MapStruct

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

引入依赖

	<properties>
        <mapstruct.version>1.3.1.Final</mapstruct.version>
    </properties>

 	<dependencies>
		<!--lombok 辅助工具-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-jdk8</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>
	</dependencies>

准备几个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<tuan.entity.StudentVO>
     */
    List<StudentVO> students2StudentVOs(List<Student> studentList);

    /**
     *  Map<Obj> 装换Map<String>
     * @author DuanLinpeng
     * @date 2021/01/10 13:11
     * @param source
     * @return java.util.Map<java.lang.String,java.lang.String>
     */
    @MapMapping(valueDateFormat = "dd-MM-yyyy")
    Map<String, String> LocalDateMapToStringStringMap(Map<Long, LocalDate> source);
    /**
     *  Set<Obj> 装换Set<指定类型>
     * @author DuanLinpeng
     * @date 2021/01/10 13:17
     * @param integers
     * @return java.util.Set<java.lang.String>
     */
    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<Object> 类型装换出自定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<Integer> To Set<String> 》》"+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/

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值