当前位置:网站首页>遇到MapStruct后,再也不手写PO,DTO,VO对象之间的转换了
遇到MapStruct后,再也不手写PO,DTO,VO对象之间的转换了
2022-08-04 20:20:00 【51CTO】

介绍
在工作中,我们经常要进行各种对象之间的转换。
PO:persistent object 持久对象,对应数据库中的一条记录
VO:view object 表现层对象,最终返回给前端的对象
DTO:data transfer object数据传输对象,如dubbo服务之间传输的对象
如果这些对象的属性名相同还好,可以用如下工具类赋值
Spring BeanUtils
Cglib BeanCopier
避免使用Apache BeanUtils,性能较差
如果属性名不同呢?如果是将多个PO对象合并成一个VO对象呢?好在有MapStruct神器,可以帮助我们快速转换
在pom文件中加入如下依赖即可
<
dependency
>
<
groupId
>org.mapstruct
</
groupId
>
<
artifactId
>mapstruct-jdk8
</
artifactId
>
<
version
>1.2.0.CR1
</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.mapstruct
</
groupId
>
<
artifactId
>mapstruct-processor
</
artifactId
>
<
version
>1.2.0.CR1
</
version
>
<
scope
>provided
</
scope
>
</
dependency
>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
对象互转
@Mapper
public
interface
StudentMapper {
StudentMapper
INSTANCE
=
Mappers.
getMapper(
StudentMapper.
class);
@Mappings({
@Mapping(
source
=
"name",
target
=
"studentName"),
@Mapping(
source
=
"age",
target
=
"studentAge")
})
StudentVO
po2Vo(
StudentPO
studentPO);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 新建一个Mapper接口,上面加上@Mapper注解
- 新建一个成员变量INSTANCE
- 用@Mapping注解指定映射关系,名字相同的就不用再指定了,会自动映射
测试效果如下,名字不同且没有指定映射关系的会被设置为null
@Test
public
void
studentPo2Vo() {
StudentPO
studentPO
=
StudentPO.
builder().
id(
10).
name(
"test")
.
age(
24).
className(
"教室名").
build();
StudentVO
studentVO
=
StudentMapper.
INSTANCE.
po2Vo(
studentPO);
// StudentVO(id=10, studentName=test, studentAge=24, schoolName=null)
System.
out.
println(
studentVO);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
List互转
@Mapper
public
interface
StudentMapper {
StudentMapper
INSTANCE
=
Mappers.
getMapper(
StudentMapper.
class);
@Mappings({
@Mapping(
source
=
"name",
target
=
"studentName"),
@Mapping(
source
=
"age",
target
=
"studentAge")
})
StudentVO
po2Vo(
StudentPO
studentPO);
List
<
StudentVO
>
poList2VoList(
List
<
StudentPO
>
studentPO);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
List类型互转的映射规则会用单个对象的映射规则,看测试效果
@Test
public
void
poList2VoList() {
List
<
StudentPO
>
studentPOList
=
new
ArrayList
<>();
for (
int
i
=
1;
i
<=
2;
i
++) {
StudentPO
studentPO
=
StudentPO.
builder().
id(
i).
name(
String.
valueOf(
i)).
age(
i).
build();
studentPOList.
add(
studentPO);
}
List
<
StudentVO
>
studentVOList
=
StudentMapper.
INSTANCE.
poList2VoList(
studentPOList);
// [StudentVO(id=1, studentName=1, studentAge=1, schoolName=null),
// StudentVO(id=2, studentName=2, studentAge=2, schoolName=null)]
System.
out.
println(
studentVOList);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
多个对象映射一个对象
我们用SchoolPO和StudentPO来映射SchoolStudentVO
测试例子如下
@Test
public
void
mergeVo() {
SchoolPO
schoolPO
=
SchoolPO.
builder().
name(
"学校名字").
build();
StudentPO
studentPO
=
StudentPO.
builder().
name(
"学生名字").
build();
SchoolStudentVO
schoolStudentVO
=
StudentMapper.
INSTANCE.
mergeVo(
schoolPO,
studentPO);
// SchoolStudentVO(schoolName=学校名字, studentName=学生名字)
System.
out.
println(
schoolStudentVO);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
当然还有其他的骚操作,这里就简单介绍一个比较实用的技巧,有兴趣的可以看官方的example
https://github.com/mapstruct/mapstruct-examples
转换的时候指定方法
当我们想把PersonVO转换为PersonPO,PersonPO中的gender是一个枚举,PersonVO中的gender是一个int类型,如何把枚举转为枚举的value值呢?
在@Mapping注解中通过qualifiedByName属性指定转换的方法
@Mapper
public
interface
StudentMapper {
StudentMapper
INSTANCE
=
Mappers.
getMapper(
StudentMapper.
class);
@Mappings({
@Mapping(
source
=
"gender",
target
=
"gender",
qualifiedByName
=
"convertGender"),
})
PersonPO
vo2Po(
PersonVO
personVO);
@Named(
"convertGender")
default
Integer
convertTargetType(
GenderEnum
genderEnum) {
return
genderEnum.
getValue();
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
测试类如下
实现原理
MapStruct帮你对接口生成了一个实现类,下面就是生成的实现类,从class文件夹中可以看到
public
class
StudentMapperImpl
implements
StudentMapper {
@Override
public
StudentVO
po2Vo(
StudentPO
studentPO) {
if (
studentPO
==
null ) {
return
null;
}
StudentVO
studentVO
=
new
StudentVO();
studentVO.
setStudentAge(
studentPO.
getAge() );
studentVO.
setStudentName(
studentPO.
getName() );
studentVO.
setId(
studentPO.
getId() );
return
studentVO;
}
@Override
public
List
<
StudentVO
>
poList2VoList(
List
<
StudentPO
>
studentPO) {
if (
studentPO
==
null ) {
return
null;
}
List
<
StudentVO
>
list
=
new
ArrayList
<
StudentVO
>(
studentPO.
size() );
for (
StudentPO
studentPO1 :
studentPO ) {
list.
add(
po2Vo(
studentPO1 ) );
}
return
list;
}
@Override
public
SchoolStudentVO
mergeVo(
SchoolPO
schoolPO,
StudentPO
studentPO) {
if (
schoolPO
==
null
&&
studentPO
==
null ) {
return
null;
}
SchoolStudentVO
schoolStudentVO
=
new
SchoolStudentVO();
if (
schoolPO
!=
null ) {
schoolStudentVO.
setSchoolName(
schoolPO.
getName() );
}
if (
studentPO
!=
null ) {
schoolStudentVO.
setStudentName(
studentPO.
getName() );
}
return
schoolStudentVO;
}
@Override
public
PersonPO
vo2Po(
PersonVO
personVO) {
if (
personVO
==
null ) {
return
null;
}
PersonPO
personPO
=
new
PersonPO();
personPO.
setGender(
convertTargetType(
personVO.
getGender() ) );
personPO.
setAge(
personVO.
getAge() );
return
personPO;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
欢迎关注

参考博客
[0]http://www.tianshouzhi.com/api/tutorials/mapstruct
[1]https://www.jianshu.com/p/3f20ca1a93b0
边栏推荐
- How to manually download and install SAP Fiori tools - Extension Pack for Visual Studio Code
- c sqlite ... ...
- Order of lds links
- KubeSphere简介,功能介绍,优势,架构说明及应用场景
- C#移动OA办公系统源码(基于微信企业号)
- MySQL stored procedure introduction, creation, case, delete, view "recommended collection"
- 零知识证明——zkSNARK证明体系
- 成品升级程序
- 【CAS:2306109-91-9 |胺-PEG4-脱硫生物素】价格
- 阿里的arthas使用,入门报错:Unable to attach to 32-bit process running under WOW64
猜你喜欢

【AGC】构建服务1-云函数示例

手撕SparkSQL五大JOIN的底层机制

Quantitative trading robot system development

微信小程序云开发 | 赠、删、改城市名称信息的应用实现

多商户商城系统功能拆解22讲-平台端分销商品

"WAIC 2022 · hackers marathon" two ants wealth competition invited you to fight!

如何推动乡村振兴的落地

C语言小笔记+题

The book "The Essence of Alipay Experience Design", a record of knowledge related to testing

刷题-洛谷-P1200 你的飞碟在这儿Your Ride Is Here
随机推荐
win10 uwp 修改图片质量压缩图片
Getting Started with Lattice Passwords
lds链接的 顺序问题
零知识证明笔记——私密交易,pederson,区间证明,所有权证明
腾讯云胡启明:Kubernetes云上资源的分析与优化
使用 Allatori 进行 Jar 包混淆
win10 uwp modify picture quality compress picture
新式茶饮,卷完水果还能卷什么?
Apache服务器的配置[通俗易懂]
ASP.NET商贸进销存管理系统源码(带数据库文档)源码免费分享
JSD-2204-酷莎商城(管理员模块)-密码加密-Day10
37.轮播图
如何手动下载并安装 Visual Studio Code 的 SAP Fiori tools - Extension Pack
Initialization process of SAP UI5
LED的C语言应用程序
win10终端中如何切换磁盘
二叉树的前序遍历
完善的交叉编译环境记录 peta 生成的shell 脚本
vs Code runs a local web server
Qt Designer生成的图形可以自适应窗口的大小变化