Orika是java Bean映射框架,可以实现从一个对象递归拷贝数据至另一个对象。在开发多层应用程序中非常有用。在这些层之间交换数据时,通常为了适应不同API需要转换一个实例至另一个实例。最常见的就是实体对象和数据显示层(VO,DTO等)的转换。
有很多方法可以实现:硬代码拷贝或Dozer实现bean映射等。总之,需要简化不同层对象之间映射过程。
Orika使用字节码生成器创建开销最小的快速映射,比其他基于反射方式实现(如,Dozer,Bean Copy)更快。
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.4.6</version>
</dependency>
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.converter.BidirectionalConverter;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.Type;
import ma.glasnost.orika.metadata.TypeFactory;
import java.math.BigDecimal;
import java.util.List;
/**
* 简单封装orika, 实现深度的BeanOfClasssA<->BeanOfClassB复制
* <p>
* 不要是用Apache Common BeanUtils进行类复制,每次就行反射查询对象的属性列表, 非常缓慢.
* <p>
* 注意: 需要参考本模块的POM文件,显式引用orika.
*/
public class BeanMapper {
/**
* beanMapper 门面
*/
private static MapperFacade mapper;
static {
//mapNulls 表示 原对象中的null不会拷贝到目标对象
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().mapNulls(false).build();
mapperFactory.getConverterFactory().registerConverter(new BigDecimal2IntConverter());
mapper = mapperFactory.getMapperFacade();
}
/**
* BigDecimal与Integer互转转换器
*/
static class BigDecimal2IntConverter extends BidirectionalConverter<BigDecimal, Integer> {
@Override
public Integer convertTo(BigDecimal bigDecimal, Type<Integer> type) {
return bigDecimal.intValue();
}
@Override
public BigDecimal convertFrom(Integer integer, Type<BigDecimal> type) {
return new BigDecimal(integer);
}
}
/**
* 简单的复制出新类型对象.
* <p>
* 通过source.getClass() 获得源Class
* @param <S> 源对象类型
* @param <D> 目标对象类型
* @param source 源对象
* @param destinationClass 目标类型
* @return 目标对象
*/
public static <S, D> D map(S source, Class<D> destinationClass) {
return mapper.map(source, destinationClass);
}
/**
* 极致性能的复制出新类型对象.
* <p>
* 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入
* @param <S> 源对象类型
* @param <D> 目标对象类型
* @param source 源对象
* @param sourceType 源对象类型
* @param destinationType 目标类型
* @return 目标对象
*/
public static <S, D> D map(S source, Type<S> sourceType, Type<D> destinationType) {
return mapper.map(source, sourceType, destinationType);
}
/**
* 简单的复制出新对象列表到ArrayList
* <p>
* 不建议使用mapper.mapAsList(Iterable<S>,Class<D>)接口, sourceClass需要反射,实在有点慢
* @param <S> 源对象类型
* @param <D> 目标对象类型
* @param sourceList 源对象列表
* @param sourceClass 源对象类 class
* @param destinationClass 目标类 class
* @return 目标对象对象
*/
public static <S, D> List<D> mapList(Iterable<S> sourceList, Class<S> sourceClass, Class<D> destinationClass) {
return mapper.mapAsList(sourceList, TypeFactory.valueOf(sourceClass), TypeFactory.valueOf(destinationClass));
}
/**
* 极致性能的复制出新类型对象到ArrayList.
* <p>
* 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入
* @param <S> 源对象类型
* @param <D> 目标对象类型
* @param sourceList 源对象列表
* @param sourceType 源对象类型
* @param destinationType 目标类型
* @return 目标对象对象列表
*/
public static <S, D> List<D> mapList(Iterable<S> sourceList, Type<S> sourceType, Type<D> destinationType) {
return mapper.mapAsList(sourceList, sourceType, destinationType);
}
/**
* 简单复制出新对象列表到数组
* 通过source.getComponentType() 获得源Class
* destinationType
* @param <S> 源对象类型
* @param <D> 目标对象类型
* @param destination 目标对象数组
* @param source 源对象数组
* @param destinationClass 目标类型
* @return 目标对象对象数组
*/
public static <S, D> D[] mapArray(final D[] destination, final S[] source, final Class<D> destinationClass) {
return mapper.mapAsArray(destination, source, destinationClass);
}
/**
* 极致性能的复制出新类型对象到数组
* <p>
* 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入
* @param <S> 源对象类型
* @param <D> 目标对象类型
* @param destination 目标对象数组
* @param source 源对象数组
* @param sourceType 源对象类型
* @param destinationType 源对象类型
* @return 目标对象数组
*/
public static <S, D> D[] mapArray(D[] destination, S[] source, Type<S> sourceType, Type<D> destinationType) {
return mapper.mapAsArray(destination, source, sourceType, destinationType);
}
/**
* 预先获取orika转换所需要的Type,避免每次转换.
* @param <E> 对象类型
* @param rawType 要转换的类型
* @return 转换后的类型
*/
public static <E> Type<E> getType(final Class<E> rawType) {
return TypeFactory.valueOf(rawType);
}
/**
* 把源对象中的属性拷贝到目标对象,源对象中的null属性不拷贝到目标对象。
*
* @param sourceObject 源对象
* @param destinationObject 目标对象
* @param <S> 源对象
* @param <D> 目标对象
*/
public static <S, D> void map(S sourceObject, D destinationObject) {
mapper.map(sourceObject, destinationObject);
}
}