mapstruct解放Java对象转换
摘要
当前web后端开发,都是使用多层工程结构,需要在VO,BO,DTO,DO等各种数据结构中相互转换。这些转换代码都是些比较简单的字段映射,类型转换,重复性工作比较高,可以使用一些工具解放我们的双手
技术方案
实现类转换的方案很多,不同方案有优缺点,需要开发者自行取舍
方案 |
优点 |
缺点 |
---|---|---|
手写代码 |
1. 灵活性高 2.方便后续重构 |
1. 重复性工作多 2. 手写代码容易遗漏掉有些字段 |
BeanUtils.copyProperties 使用反射实现 |
1. 使用简单 2. Apache 的包效率比较低,spring的包效率可以接受 |
1. 复杂场景支持不足,控制copy粒度太粗 2. 不易重构 |
mapstruct |
1. 灵活性高支持简单,复杂,嵌套,自定义扩展等多种手段 2. 编译期生成,没有效率问题 |
不方便后续重构 |
方便后续重构方便后续重构的意思是当你需要更改DTO字段时,可以利用编译器的引用关系直接refactor掉
综上考虑mapstruct方案优于beanutils.copy,和手写方案对比,有一定劣势,需要取舍。个人意见,对于改字段重构,这种应该通过测试用例去保证,而不是依赖编辑器的功能。此外使用mapstruct进行转换后,类引用关系还在,重构可以通过识别类的粒度,来保证不出错。如果再考虑到手工党的出错概率,和开发效率mapstruct显然更优。
实现
- 引入依赖包
<properties>
<org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
</properties>
...
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>
- 为maven compile plugin 设置annotation processor
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source> <!-- depending on your project -->
<target>1.8</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
- IDEA 安装一个mapstruct 插件 有了这个插件后,可以找到映射类的属性,一些拼写校验
常用用法
默认情况下,当属性值与目标实体的名称相同时,就会隐式映射
其他通用转换
属性值不相同时
@Mapping(target="dateEnd", source="end")
ExampleVO doToVO(ExampleDO do);
Collection对象转换
@Mapping(target="dateEnd", source="end")
ExampleVO doToVO(ExampleDO do);
List<ExampleVO> doToVOS(List<ExampleDO> dos)
JAVA 构造器
通过expression 来调用Java代表
@Mapping(target="dateEnd", expression="java(new java.util.Date())"
ExampleVO doToVO(ExampleDO do);
qualifiedByName
如果构造器满足不了,还可以自定义方法,然后再调用
@Mapping(target="dateEnd", qualifiedByName="format", source="end")
ExampleVO doToVO(ExampleDO do);
@Named("format")
default Date formatDate(Long date) {
xxx
}
接口默认实现
mapstruct是用户定义接口,然后自动生成实现类,如果转换类中有非常定制的转换,不想通过mapstruct来转换,我们可以直接使用接口默认实现
当然还有其他功能可以使用,比如Decorator,这里不再一一列举,更多丰富的功能可以查看mapstruct 细节使用
参考
https://blog.csdn.net/w605283073/article/details/107371462
mapstruct 细节使用
- 危险:会话固定攻击漏洞,你们的系统都堵上了吗?
- 深度学习入门者必看:25个你一定要知道的概念
- 如何在CM中启用YARN的使用率报告
- 如何修改CDSW服务的DNS和HOSTNAME
- 想尝试搭建图像识别系统?这里有一份TensorFlow速成教程
- 如何查看集成Sentry后Hive作业的真实用户
- 如何在Impala中实现拉链表
- 多图见证模拟机器人的逆天成长:论进化策略在强化学习中的应用
- Hue禁止用户下载数据问题分析
- 如何在RedHat6上使用Bind搭建DNS服务
- 如何使用Cloudera Manager升级Spark2.1版本至Spark2.2
- Cloudera Manager分发Parcel异常分析
- 如何在Hue中配置Impala的负载均衡
- 35行代码实现千万级别字典的快速去重
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Spring @Autowired npe example:Why your Spring @Autowired component is null
- Spring JPA 查询创建
- 『Python动手学』Python处理.mat文件
- Swift 打开三方地图 腾讯地图、百度地图、高德地图、Apple 地图
- 初学者应该看的JavaScript Promise 完整指南
- React Advanced Topics
- try catch引发的性能优化深度思考
- 用于自动驾驶车辆视觉定位的地图存储:ORB-SLAM2的一种拓展
- c# 动态产生控件 注册动态控件事件
- leetcode 一些算法题及答案
- 得分--UVa1585
- 如何计算一个程序的运行时间
- c语言输入回车结束输入
- C# devExpress BandedGridView属性 备忘
- 结构体的应用及所有形式