一款PO VO DTO 转换神器,求求你别在到处找工具类了!

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 一款PO VO DTO 转换神器,求求你别在到处找工具类了!

一款PO VO DTO 转换神器,求求你别在到处找工具类了!
作者:bettermann toutiao.com/i6891531055631696395/

老铁们是不是经常为写一些实体转换的原始代码感到头疼,尤其是实体字段特别多的时候。介绍一个开源项目 mapstruct ,可以轻松优雅的进行转换,简化你的代码。当然有的人喜欢写get set,或者用BeanUtils 进行复制,代码只是工具,本文只是提供一种思路。

先贴下官网地址吧:https://mapstruct.org/

废话不多说,上代码:

pom 配置:


properties
        project.build.sourceEncodingUTF-8/project.build.sourceEncoding
        maven.compiler.source1.8/maven.compiler.source
        maven.compiler.target1.8/maven.compiler.target
        org.mapstruct.version1.4.1.Final/org.mapstruct.version
        org.projectlombok.version1.18.12/org.projectlombok.version
/properties

dependencies
        dependency
            groupIdorg.mapstruct/groupId
            artifactIdmapstruct/artifactId
            version${org.mapstruct.version}/version
        /dependency

        !-- lombok dependencies should not end up on classpath --
        dependency
            groupIdorg.projectlombok/groupId
            artifactIdlombok/artifactId
            version${org.projectlombok.version}/version
            scopeprovided/scope
        /dependency

        !-- idea 2018.1.1 之前的版本需要添加下面的配置,后期的版本就不需要了,可以注释掉,
我自己用的2019.3 --
     dependency
            groupIdorg.mapstruct/groupId
            artifactIdmapstruct-processor/artifactId
            version${org.mapstruct.version}/version
            scopeprovided/scope
        /dependency

/dependencies

build
        plugins
            plugin
                groupIdorg.apache.maven.plugins/groupId
                artifactIdmaven-compiler-plugin/artifactId
                version3.8.1/version
                configuration
                    source1.8/source
                    target1.8/target
                    annotationProcessorPaths
                        path
                            groupIdorg.projectlombok/groupId
                            artifactIdlombok/artifactId
                            version${org.projectlombok.version}/version
                        /path
                        path
                            groupIdorg.mapstruct/groupId
                            artifactIdmapstruct-processor/artifactId
                            version${org.mapstruct.version}/version
                        /path
                    /annotationProcessorPaths
                /configuration
            /plugin
        /plugins
    /build

关于lombok和mapstruct的版本兼容问题多说几句,maven插件要使用3.6.0版本以上、lombok使用1.16.16版本以上,另外编译的lombok mapstruct的插件不要忘了加上。否则会出现下面的错误:No property named “aaa” exists in source parameter(s). Did you mean “null”?

这种异常就是lombok编译异常导致缺少get setter方法造成的。还有就是缺少构造函数也会抛异常。


@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    private String name;
    private int age;
    private GenderEnum gender;
    private Double height;
    private Date birthday;

}
public enum GenderEnum {
    Male("1", "男"),
    Female("0", "女");

    private String code;
    private String name;

    public String getCode() {
        return this.code;
    }

    public String getName() {
        return this.name;
    }

    GenderEnum(String code, String name) {
        this.code = code;
        this.name = name;
    }
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class StudentVO {
    private String name;
    private int age;
    private String gender;
    private Double height;
    private String birthday;
}
@Mapper
public interface StudentMapper {

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

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

}

实体类是开发过程少不了的,就算是用工具生成肯定也是要有的,需要手写的部分就是这个Mapper的接口,编译完成后会自动生成相应的实现类

然后就可以直接用mapper进行实体的转换了


public class Test {

    public static void main(String[] args) {

        Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();
        System.out.println(student);
        //这行代码便是实际要用的代码
        StudentVO studentVO = StudentMapper.INSTANCE.student2StudentVO(student);
        System.out.println(studentVO);

    }

}

mapper可以进行字段映射,改变字段类型,指定格式化的方式,包括一些日期的默认处理。

可以手动指定格式化的方法:


@Mapper
public interface StudentMapper {

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

    @Mapping(source = "gender", target = "gender")
    @Mapping(source = "birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
    StudentVO student2StudentVO(Student student);

    default String getGenderName(GenderEnum gender) {
        return gender.getName();
    }

}

上面只是最简单的实体映射处理,下面介绍一些高级用法

1.List 转换

属性映射基于上面的mapping配置


@Mapper
public interface StudentMapper {

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

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


    ListStudentVO students2StudentVOs(ListStudent studentList);

}
public static void main(String[] args) {

    Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();

    ListStudent list = new ArrayList();
    list.add(student);
    ListStudentVO result = StudentMapper.INSTANCE.students2StudentVOs(list);
    System.out.println(result);
}

2.多对象转换到一个对象


@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    private String name;
    private int age;
    private GenderEnum gender;
    private Double height;
    private Date birthday;

}
@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class Course {

    private String courseName;
    private int sortNo;
    private long id;

}
@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;
}
@Mapper
public interface StudentMapper {

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

    @Mapping(source = "student.gender.name", target = "gender")
    @Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Mapping(source = "course.courseName", target = "course")
    StudentVO studentAndCourse2StudentVO(Student student, Course course);

}
public class Test {

    public static void main(String[] args) {

        Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();
        Course course = Course.builder().id(1L).courseName("语文").build();

        StudentVO studentVO = StudentMapper.INSTANCE.studentAndCourse2StudentVO(student, course);
        System.out.println(studentVO);
    }

}

一款PO VO DTO 转换神器,求求你别在到处找工具类了!3.默认值


@Mapper
public interface StudentMapper {

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

    @Mapping(source = "student.gender.name", target = "gender")
    @Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Mapping(source = "course.courseName", target = "course")
    @Mapping(target = "name", source = "student.name", defaultValue = "张三")
    StudentVO studentAndCourse2StudentVO(Student student, Course course);

}

END

推荐好文

强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

为什么MySQL不推荐使用uuid或者雪花id作为主键?

为什么建议大家使用 Linux 开发?爽(外加七个感叹号)

IntelliJ IDEA 15款 神级超级牛逼插件推荐(自用,真的超级牛逼)

炫酷,SpringBoot+Echarts实现用户访问地图可视化(附源码)

记一次由Redis分布式锁造成的重大事故,避免以后踩坑!

十分钟学会使用 Elasticsearch 优雅搭建自己的搜索系统(附源码)

一款PO VO DTO 转换神器,求求你别在到处找工具类了!

原文始发于微信公众号(Java笔记虾):一款PO VO DTO 转换神器,求求你别在到处找工具类了!

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 一款PO VO DTO 转换神器,求求你别在到处找工具类了!


 上一篇
介绍一个适合深入学习并实战的SpringBoot项目 介绍一个适合深入学习并实战的SpringBoot项目
项目简介 spring-boot-demo是一个用来深入学习并实战SpringBoot的项目,目前总共包含66个集成demo,已经完成54个,每个集成demo都有完整的代码和模块简介,并且作者还在不断更新中。 该项目已经成功集成的demo:
下一篇 
你不知道的redis——主从复制,因为该命令redis作者曾摊上事 你不知道的redis——主从复制,因为该命令redis作者曾摊上事
作者:Dark_King_ blog.csdn.net/b379685397/article/details/109147469 一、什么是主从复制主从复制就是我们建立数据存档的时候,将一份数据进