我们有这样一个场景,有一个StudentDto类,还有一个StudentVo类
@Data public class StudentDto { private String id; private String code; private String sex; private String userName; } @Data public class StudentVo { private String id; private String name; private String code; private String age; private String score; private String sex; }如果我们知道StudentVo的值,需要将StudentVo的属性拷贝到StudentDto中,你会怎么做。
”StudentVo的值如下
public StudentVo initVo() { StudentVo studentVo = new StudentVo(); studentVo.setId("1"); studentVo.setAge("27"); studentVo.setName("Lvshen"); studentVo.setCode("001"); studentVo.setScore("100"); studentVo.setSex("male"); return studentVo; }传统的解决方法,通过getter/setter方法将对应的属性值进行拷贝。
@org.junit.Test public void test3() { StudentVo studentVo = initVo(); StudentDto studentDto = new StudentDto(); studentDto.setCode(studentVo.getCode()); studentDto.setId(studentVo.getId()); studentDto.setSex(studentVo.getSex()); studentDto.setUserName(studentVo.getName()); System.out.println(studentDto); }测试结果
看了上面的方法,你可能觉得不是很简单么。但如果属性非常多,比如有20多个。用上面的方法就会不美观,满屏的getter/setter方法,看着都眼花。
这时我们就可以使用BeanUtils.copyProperties方法啦,这里的BeanUtils是Spring的,而不是apache的。
@org.junit.Test public void test2() { StudentVo studentVo = initVo(); StudentDto studentDto = new StudentDto(); BeanUtils.copyProperties(studentVo,studentDto); System.out.println(studentDto); }测试结果
我们还可以使用性能更优越的MapStruct,你可能没有听过这个东西。没关系,我们直接上代码。
MapStruct是一个可以生成类型安全的,高性能的且无依赖的 JavaBean 映射代码的注解处理器,可以在编译期生成对应的mapping,既没有BeanUtils等工具使用反射的性能问题,又免去了自己写映射代码的繁琐。
引入Maven依赖
<dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.3.1.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.3.1.Final</version> </dependency>我们先编写一个StudentConverter类
@Mapper public interface StudentConverter { StudentConverter INSTANCE = Mappers.getMapper(StudentConverter.class); @Mappings(@Mapping(source = "name",target = "userName")) StudentDto vo2dto(StudentVo vo); }这里的@Mapper来源于org.mapstruct.Mapper,用来说明这是一个实体转换类接口。
@Mappings用来声明成员属性的映射,source = "name",target = "userName"即将StudentVo中name的值拷贝给StudentDto中的userName,如果属性名称相同,就不需要做这个映射。
测试结果
@org.junit.Test public void test1() { StudentVo studentVo = initVo(); StudentDto studentDto = StudentConverter.INSTANCE.vo2dto(studentVo); System.out.println(studentDto); }你以为MapStruct只能进行实体之间的拷贝?NO,MapStruct还可以进行List之间的拷贝,这个就太牛了。
@Mapper public interface StudentConverter { StudentConverter INSTANCE = Mappers.getMapper(StudentConverter.class); @Mappings(@Mapping(source = "name",target = "userName")) StudentDto vo2dto(StudentVo vo); List<StudentDto> listVo2dto(List<StudentVo> vos); }测试
public void test() { List<StudentVo> voList = initVoList(); List<StudentDto> studentDtos = StudentConverter.INSTANCE.listVo2dto(voList); System.out.println(studentDtos); }测试结果
当然MapStruct等功能远比你想象的要多,有兴趣的可以看看这篇文章
“https://www.cnblogs.com/homejim/p/11313128.html
”市面上 BeanUtils底层是使用反射的,我们知道使用反射会影响性能。而且BeanUtils需要类型和名称都一样才会进行映射, 但在很多时候, 由于不同的团队之间使用的名词不一样, 还是需要很多的手动使用getter/setter。
于是MapStruct诞生了。
MapSturct 是一个生成类型安全, 高性能且无依赖的 JavaBean 映射代码的注解处理器(annotation processor)。
它有下面几个特点:
“基于注解的处理器
可以自定义 JavaBean 之间的属性映射
类型安全, 高性能, 无依赖性
”编译之后会生成方法实现
实现的类、方法如下
该工具可以帮我们实现 JavaBean 之间的转换, 通过注解的方式。通过 MapStruct 来生成的代码, 其类似于人手写。速度上可以得到保证。
我写出这样干净的代码,老板直夸我
云南丽江旅游攻略
使用ThreadLocal怕内存泄漏?
Java进阶之路思维导图
程序员必看书籍推荐
3万字的Java后端面试总结(附PDF)
扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料
1.回复"java" 获取java电子书; 2.回复"python"获取python电子书; 3.回复"算法"获取算法电子书; 4.回复"大数据"获取大数据电子书; 5.回复"spring"获取SpringBoot的学习视频。 6.回复"面试"获取一线大厂面试资料 7.回复"进阶之路"获取Java进阶之路的思维导图 8.回复"手册"获取阿里巴巴Java开发手册(嵩山终极版) 9.回复"总结"获取Java后端面试经验总结PDF版 10.回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF) 11.回复"并发导图"获取Java并发编程思维导图(xmind终极版)另:点击【我的福利】有更多惊喜哦。