在平时开发过程中,我们经常需要处理DTO、VO、Entity等对象的转换,肯定不希望代码中出现大量的setter/getter的赋值操作。通常情况下,大多数是同名属性的转换。类复制工具有很多,比较常用的有 mapstruct、Spring BeanUtils、Apache BeanUtils、dozer 等。
这些类复制工具之间的差异、性能比较比较如下:
Orika是java Bean映射框架,可以实现从一个对象递归拷贝数据至另一个对象,它使用字节码生成器创建开销最小的快速映射,比其他基于反射方式实现更快。
不多扯了,其实写这篇文章,主要是教小伙伴们如何使用Orika,直接上代码吧。
1、引入maven依赖
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.5.1</version>
</dependency>
2、编写容器注入类,避免重复创建映射工厂类。
正常使用的时候映射类是可以重复使用的,但是本次发生的问题的地方在使用的时候,新构建了映射工厂,这样就导致每次使用此拷贝方式的时候不仅会重新创建一个映射类还会创建一个映射工厂类,而且这个问题方法使用场景是一个异步批量接单的场景,整点大量的异步mq请求进系统后,产生大量的映射类文件,将元空间打OOM,从而频繁的触发fullgc。(来源:blog.csdn.net/qq_39711319…)
@Configuration
public class MapperFacotoryAutoWire {
@Bean
public MapperFactory getFactory(){
return new DefaultMapperFactory.Builder().build();
}
}
3、如何使用
@Resource
private MapperFactory mapperFactory;
@Resource
private MapperFactory mapperFactory;
public void copyBean(){
UserDto userDto = new UserDto("101","syx","男",20);
// 因为存在字段不一样,需要手动映射一下
// 如果所有字段一样,则不用写mapperFactory.classMap()方法
mapperFactory.classMap(UserDto.class, UserVo.class)
.field("age","userAge")//不一样的字段映射
.byDefault()//剩余的字段映射
.register();
UserVo userVo = mapperFactory.getMapperFacade().map(userDto, UserVo.class);
System.out.println(userVo.toString());
//UserVo(id=101, name=syx, sex=男, userAge=20)
}
public void copyList(){
List<UserDto> userDtos = new ArrayList<>();
UserDto userDto1 = new UserDto("101","syx1","男",21);
UserDto userDto2 = new UserDto("102","syx2","男",22);
UserDto userDto3 = new UserDto("103","syx3","男",23);
userDtos.add(userDto1);
userDtos.add(userDto2);
userDtos.add(userDto3);
//手动配置不一样的字段转换
mapperFactory.classMap(UserDto.class, UserVo.class)
.field("age","userAge")//不一样的字段映射
.byDefault()//剩余的字段映射
.register();
//转换List
List<UserVo> userVos = mapperFactory.getMapperFacade().mapAsList(userDtos, UserVo.class);
System.out.println(userVos.toString());
//[UserVo(id=101, name=syx1, sex=男, userAge=21), UserVo(id=102, name=syx2, sex=男, userAge=22), UserVo(id=103, name=syx3, sex=男, userAge=23)]
}