使用 Orika 实现 Java Bean 映射工具类

使用 Orika 实现 Java Bean 映射工具类

  • 1.引入 orika 的 jar 包
  • 2.创建映射工具类
  • 3.使用映射工具类
  • 4.结语

orika 是 Java Bean 映射框架,可以实现从一个对象递归拷贝数据至另一个对象。这样我们可以将数据在实体,DTO,VO之间切换。关于 Bean 映射,其实 BeanUtil中 的 copyProperties() 方法也可以实现,但是如果名字相同类型不同是不能直接复制的,而 orika 却可以解决这个问题。

下面将具体介绍如何使用 orika 实现映射。

1.引入 orika 的 jar 包

现在用的大部分都是使用的 maven 文件,可以在 pom.xml 文件中引入下列配置即可。

<dependency>
    <groupId>ma.glasnost.orikagroupId>
    <artifactId>orika-coreartifactId>
    <version>1.5.4version>
dependency>

2.创建映射工具类

我在之前使用使用的时候,使用的并不是单例模式,然而造成了内存溢出的情况,后来采用单例的模式,解决了这个问题。这里单例使用的是枚举方式实现的,也是效率比较高的一种吧。

  • 具体工具类代码实现:
package com.jiafly.libra.common.utils;

import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.ClassMapBuilder;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 映射工具类
 *
 * @author 东邪Jiafly
 */
public enum MapperUtils {

    /**
     * 实例
     */
    INSTANCE;

    /**
     * 默认字段工厂
     */
    private static final MapperFactory MAPPER_FACTORY = new DefaultMapperFactory.Builder().build();

    /**
     * 默认字段实例
     */
    private static final MapperFacade MAPPER_FACADE = MAPPER_FACTORY.getMapperFacade();

    /**
     * 默认字段实例集合
     */
    private static Map<String, MapperFacade> CACHE_MAPPER_FACADE_MAP = new ConcurrentHashMap<>();

    /**
     * 映射实体(默认字段)
     *
     * @param toClass 映射类对象
     * @param data    数据(对象)
     * @return 映射类对象
     */
    public <E, T> E map(Class<E> toClass, T data) {
        return MAPPER_FACADE.map(data, toClass);
    }

    /**
     * 映射实体(自定义配置)
     *
     * @param toClass   映射类对象
     * @param data      数据(对象)
     * @param configMap 自定义配置
     * @return 映射类对象
     */
    public <E, T> E map(Class<E> toClass, T data, Map<String, String> configMap) {
        MapperFacade mapperFacade = this.getMapperFacade(toClass, data.getClass(), configMap);
        return mapperFacade.map(data, toClass);
    }

    /**
     * 映射集合(默认字段)
     *
     * @param toClass 映射类对象
     * @param data    数据(集合)
     * @return 映射类对象
     */
    public <E, T> List<E> mapAsList(Class<E> toClass, Collection<T> data) {
        return MAPPER_FACADE.mapAsList(data, toClass);
    }


    /**
     * 映射集合(自定义配置)
     *
     * @param toClass   映射类
     * @param data      数据(集合)
     * @param configMap 自定义配置
     * @return 映射类对象
     */
    public <E, T> List<E> mapAsList(Class<E> toClass, Collection<T> data, Map<String, String> configMap) {
        T t = data.stream().findFirst().orElseThrow(() -> new ResourceNotExistException("映射集合,数据集合为空"));
        MapperFacade mapperFacade = this.getMapperFacade(toClass, t.getClass(), configMap);
        return mapperFacade.mapAsList(data, toClass);
    }

    /**
     * 获取自定义映射
     *
     * @param toClass   映射类
     * @param dataClass 数据映射类
     * @param configMap 自定义配置
     * @return 映射类对象
     */
    private <E, T> MapperFacade getMapperFacade(Class<E> toClass, Class<T> dataClass, Map<String, String> configMap) {
        String mapKey = dataClass.getCanonicalName() + "_" + toClass.getCanonicalName();
        MapperFacade mapperFacade = CACHE_MAPPER_FACADE_MAP.get(mapKey);
        if (Objects.isNull(mapperFacade)) {
            MapperFactory factory = new DefaultMapperFactory.Builder().build();
            ClassMapBuilder classMapBuilder = factory.classMap(dataClass, toClass);
            configMap.forEach(classMapBuilder::field);
            classMapBuilder.byDefault().register();
            mapperFacade = factory.getMapperFacade();
            CACHE_MAPPER_FACADE_MAP.put(mapKey, mapperFacade);
        }
        return mapperFacade;
    }
}

3.使用映射工具类

这个工具列中主要有四个方法来根据不同需求去映射对象。

  • map(Class toClass, T data)
    这个是普通的映射实体,主要映射命名相同的默认字段。

  • map(Class toClass, T data, Map configMap)
    这是个自定义配置的映射集合,当name

  • mapAsList(Class toClass, Collection data)
    这个是针对集合的映射

  • mapAsList(Class toClass, Collection data, Map configMap)
    这是针对集合配置并且自定义配置

4.结语

这篇主要是针对使用 Orika 的使用写了一个工具类,以方便我们在需要的时候直接使用,当然如果想对 Orika 有一些更高级的使用,可以继续阅读 Orika 的源码,分析它具体的实现原理。

我们在使用的时候直接可以使用 工具类名 . 方法名进行使用。如下:

MapperUtil.map(UserResult.class, user);

这样就可以将 User 对象转换成我们需要的 UserResult 对象返回了,是不是很方便呢?

你可能感兴趣的:(Java)