当前位置:网站首页>遇到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
边栏推荐
猜你喜欢
从卖产品到卖“链路”:20条策略 解读直播带货迭代玩法
PriorityQueue类的使用及底层原理
二叉树是否对称
Tensorflow2 环境搭建
刷题-洛谷-P1304 哥德巴赫猜想
零知识证明笔记——私密交易,pederson,区间证明,所有权证明
hash和history路由的区别
长时间序列遥感数据处理及在全球变化、物候提取、植被变绿与固碳分析、生物量估算与趋势分析等领域中的应用
Ant Group's time series database CeresDB is officially open source
ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators
随机推荐
数据安全解决方案的发展
MYSQL获取数据库的表名和表注释
C#的Dictionary字典集合按照key键进行升序和降序排列
CAS :80750-24-9(脱硫生物素 NHS 酯)
June To -.-- -..- -
vscode离线安装插件方法
动态数组底层是如何实现的
How to manually download and install SAP Fiori tools - Extension Pack for Visual Studio Code
zynq records
c sqlite ... ...
取证程序分类
Initialization process of SAP UI5
c语言小项目(三子棋游戏实现)
二叉树的前序遍历
【CAS:2306109-91-9 |胺-PEG4-脱硫生物素】价格
【TypeScript】深入学习TypeScript枚举
构建Buildroot根文件系统(I.MX6ULL)
C语言小笔记+题
nr部分计算
zynq 记录