有偿问答
面经分享
技术探讨
资料领取
登录
别再用 BeanUtils 了,这款 PO VO DTO 转换神器不香么?
社长
1年前
⋅ 443 阅读
> *来源:toutiao.com/i6891531055631696395* ### 老铁们是不是经常为写一些实体转换的原始代码感到头疼,尤其是实体字段特别多的时候。介绍一个开源项目 mapstruct ,可以轻松优雅的进行转换,简化你的代码。 当然有的人喜欢写get set,或者用BeanUtils 进行复制,代码只是工具,本文只是提供一种思路。 先贴下官网地址吧:https://mapstruct.org/ 废话不多说,上代码: pom 配置: ```
UTF-8
1.8
1.8
1.4.1.Final
1.18.12
org.mapstruct
mapstruct
${org.mapstruct.version}
org.projectlombok
lombok
${org.projectlombok.version}
provided
org.mapstruct
mapstruct-processor
${org.mapstruct.version}
provided
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
1.8
1.8
org.projectlombok
lombok
${org.projectlombok.version}
org.mapstruct
mapstruct-processor
${org.mapstruct.version}
``` 关于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方法造成的。还有就是缺少构造函数也会抛异常。学习资料:[Java进阶视频资源](https://mp.weixin.qq.com/s/jGEkHTf2X8l-wUenc-PpEw) ``` @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的接口,编译完成后会自动生成相应的实现类 ![MarkerHub](https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/20211126/6e017074aa6743d79dc90e6aea1b7b71.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); } } ``` ![MarkerHub](https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/20211126/6e017074aa6743d79dc90e6aea1b7b71.png) 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
students2StudentVOs(List
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
list = new ArrayList<>(); list.add(student); List
result = StudentMapper.INSTANCE.students2StudentVOs(list); System.out.println(result); } ``` ![MarkerHub](https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/20211126/ea7f3e1b3de248ac8f280471c1b1b636.png) ### 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); } } ``` ![MarkerHub](https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/20211126/a98cb6f212854f97b958d70df9a3bce9.png) ### 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); } ``` ![MarkerHub](https://image-1300566513.cos.ap-guangzhou.myqcloud.com/upload/images/20211126/78092c3679e74346aa2e4c4612f70b94.png)
阅读全部
全部评论:
0
条
我有话说:
@
发送
-- 目录 --
关注官方公众号:
Java问答社
接收最新有赏问答推送!
最新发布
1.
SpringBoot 接口数据加解密技巧,so easy!
2.
一个依赖搞定 Spring Boot 反爬虫,防止接口盗刷!
3.
Java8 Stream 极大简化了代码,它是如何实现的?
4.
马上大四了,秋招还是春招好?先找工作还是找实习?
5.
万字详解 Linux 常用指令(值得收藏)
6.
4年工作经验,多线程间的5种通信方式都说不出来,你敢信?
最新评论
部署文档没有了,您能提供下吗
部署文档没有了,能提供下吗
我测你的🐎
源码从哪里获取请问
想学
那篇石墨文档 没有权限查看哇