别再用 BeanUtils 了,这款 PO VO DTO 转换神器不香么?

简介: 别再用 BeanUtils 了,这款 PO VO DTO 转换神器不香么?



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

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

废话不多说,上代码:

pom 配置:

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
        <org.projectlombok.version>1.18.12</org.projectlombok.version>
</properties>
<dependencies>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
        <!-- lombok dependencies should not end up on classpath -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${org.projectlombok.version}</version>
            <scope>provided</scope>
        </dependency>
        <!-- idea 2018.1.1 之前的版本需要添加下面的配置,后期的版本就不需要了,可以注释掉,
我自己用的2019.3 -->
     <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${org.mapstruct.version}</version>
            <scope>provided</scope>
        </dependency>
</dependencies>
<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${org.projectlombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-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的接口,编译完成后会自动生成相应的实现类

image.png

然后就可以直接用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);
    List<StudentVO> students2StudentVOs(List<Student> studentList);
}
public static void main(String[] args) {
    Student student = Student.builder().name("小明").age(6).gender(GenderEnum.Male).height(121.1).birthday(new Date()).build();
    List<Student> list = new ArrayList<>();
    list.add(student);
    List<StudentVO> result = StudentMapper.INSTANCE.students2StudentVOs(list);
    System.out.println(result);
}

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

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);
    }
}

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

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);
}



相关文章
|
关系型数据库 MySQL 数据库
docker 安装 mysql 并映射数据库存放路径及配置文件
本文是博主学习docker镜像的记录,希望对大家有所帮助。
4817 0
docker 安装 mysql 并映射数据库存放路径及配置文件
|
前端开发 Java 关系型数据库
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
996 0
【SpringBoot】微服务学习笔记七:微服务中异步调用数据提交数据库的问题
|
存储 负载均衡 容灾
MySQL数据库的分布式架构和数据分片方案
MySQL数据库的分布式架构和数据分片方案
|
IDE 安全 数据管理
Visual Basic for Applications (VBA):自动化Office任务
【4月更文挑战第27天】**Visual Basic for Applications (VBA)** 是Microsoft Office中的宏语言,用于自动化Excel、Word、Outlook等应用的任务。VBA基于Visual Basic,通过编写代码控制应用行为,提升效率。文章介绍了VBA环境、基础语法,展示了在Excel(数据处理)、Word(文档管理)和Outlook(邮件自动化)中的应用。强调安全性和调试重要性,学习VBA能增强Office软件的功能,实现高效自动化工作流程。
777 0
|
SQL 缓存 Java
Data Access 之 MyBatis Plus(四)- MyBatis Plus Plugin
Data Access 之 MyBatis Plus(四)- MyBatis Plus Plugin
Data Access 之 MyBatis Plus(四)- MyBatis Plus Plugin
|
机器学习/深度学习 存储 JSON
YOLOv5的Tricks | 【Trick10】从PyTorch Hub加载YOLOv5
YOLOv5的Tricks | 【Trick10】从PyTorch Hub加载YOLOv5
1563 0
YOLOv5的Tricks | 【Trick10】从PyTorch Hub加载YOLOv5
|
缓存 Java Nacos
图文详述Nacos服务发现源码分析
图文详述Nacos服务发现源码分析
2248 0
图文详述Nacos服务发现源码分析
|
前端开发 JavaScript Java
技术分享:使用Spring Boot3.3与MyBatis-Plus联合实现多层次树结构的异步加载策略
在现代Web开发中,处理多层次树形结构数据是一项常见且重要的任务。这些结构广泛应用于分类管理、组织结构、权限管理等场景。为了提升用户体验和系统性能,采用异步加载策略来动态加载树形结构的各个层级变得尤为重要。本文将详细介绍如何使用Spring Boot3.3与MyBatis-Plus联合实现这一功能。
482 2
|
缓存 大数据 数据处理
Velocity循环详解
Velocity循环详解
|
存储 安全 Java
全面探索Spring框架中的事件处理机制
在现代应用程序中,各个组件之间的通信是至关重要的。想象一下,你的应用程序中的各个模块像是一个巨大的交响乐团,每个模块都是一位音乐家,而Spring事件机制就像是指挥家,将所有音乐家协调得天衣无缝。这种松耦合的通信方式使你的应用程序更加灵活、可维护,而且能够轻松应对变化。现在,让我们进入这个令人兴奋的音乐厅,探索Spring事件的世界。

热门文章

最新文章