Orika对象转换

Orika介绍

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);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪了个王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值