业务场景: 设计规范前提下,我们数据层传输承载的是用DTO,而到控制层返回给前端会对应定义一个VO对象,比如是一个问题单数据集合list
,数据层接收的是DTO对对象,到控制层接收后需要转换成list ,这里就涉及到要转换对象数据
对象复制的类库工具有很多 Orika是目前性能最强,同时也最流行的对象映射工具,Orika底层采用了javassist类库生成Bean映射的字节码,之后直接加载执行生成的字节码文件,在速度上比使用反射进行赋值会快很多。
阿里巴巴开发手册上强制规定避免使用Apache BeanUtils
Apache BeanUtils
底层源码为了追求完美,加了过多的包装,使用了很多反射,做了很多校验,所以导致性能较差
ma.glasnost.orika
orika-core
1.5.4
package com.hjycommunity.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 ma.glasnost.orika.metadata.Type; import ma.glasnost.orika.metadata.TypeFactory; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 对象复制工具类 **/ public class OrikaUtils { //构造一个MapperFactory private static final MapperFactory FACTORY = new DefaultMapperFactory.Builder().build(); /** * 缓存实例集合 */ private static final Map
CACHE_MAPPER = new ConcurrentHashMap<>(); private final MapperFacade mapper; public OrikaUtils(MapperFacade mapper) { this.mapper = mapper; } /** * 字段一致实体转换函数 * @param sourceEntity 源实体 * @param targetClass 目标类对象 * @param 源泛型 * @param目标泛型 * @return 目标实体 */ public static T convert(S sourceEntity, ClasstargetClass) { return convert(sourceEntity, targetClass, null); } /** * 字段不一致实体转换函数(需要字段映射) * @param sourceEntity 源实体 * @param targetClass 目标类对象 * @param refMap 配置源类与目标类不同字段名映射 * @param 源泛型 * @param目标泛型 * @return 目标实体 */ public static T convert(S sourceEntity, ClasstargetClass, Map refMap) { if (sourceEntity == null) { return null; } return classMap(sourceEntity.getClass(), targetClass, refMap).map(sourceEntity, targetClass); } /** * 字段一致集合转换函数 * @param sourceEntityList 源实体集合 * @param targetClass 目标类对象 * @param 源泛型 * @param目标泛型 * @return 目标实体集合 */ public static ListconvertList(List sourceEntityList, ClasstargetClass) { return convertList(sourceEntityList, targetClass, null); } /** * 字段不一致集合转换函数 (需要字段映射) * * @param sourceEntityList 源实体集合 * @param targetClass 目标类对象 * @param refMap 配置源类与目标类不同字段名映射 * @param 源泛型 * @param目标泛型 * @return 目标实体集合 */ public static ListconvertList(List sourceEntityList, ClasstargetClass, Map refMap) { if (sourceEntityList == null) { return null; } if (sourceEntityList.size() == 0) { return new ArrayList<>(0); } return classMap(sourceEntityList.get(0).getClass(), targetClass, refMap).mapAsList(sourceEntityList, targetClass); } /** * 字段属性转换 * @param source 源类 * @param target 目标类 * @param refMap 属性转换 */ public static void register(Class source, Class target,Map
refMap){ if (CollectionUtils.isEmpty(refMap)) { FACTORY.classMap(source, target).byDefault().register(); } else { ClassMapBuilder classMapBuilder = FACTORY.classMap(source, target); refMap.forEach(classMapBuilder::field); classMapBuilder.byDefault().register(); } } /** * 属性名称一致可用 * @param source 源数据 * @param target 目标对象 * @return OrikaUtils */ private static OrikaUtils classMap(Class source, Class target) { return classMap(source, target, null); } /** * 属性名称不一致可用 * * @param source 原对象 * @param target 目标对象 * @return OrikaUtils */ private static synchronized
OrikaUtils classMap(Class source, Class target, Map
refMap) { String key = source.getCanonicalName() + ":" + target.getCanonicalName(); if (CACHE_MAPPER.containsKey(key)) { return new OrikaUtils(CACHE_MAPPER.get(key)); } register(source,target,refMap); MapperFacade mapperFacade = FACTORY.getMapperFacade(); CACHE_MAPPER.put(key, mapperFacade); return new OrikaUtils(mapperFacade); } /** * Orika复制对象 * @param source 源数据 * @param target 目标对象 * @return target */ private P map(V source, Class target) { return mapper.map(source, target); } /** * 复制List * @param source 源对象 * @param target 目标对象 * @return P */ private
List mapAsList(List
source, Class
target) { return CollectionUtils.isEmpty(source) ? Collections.emptyList() : mapper.mapAsList(source, target); } }
/**
* 获取小区下拉列表
* @param community
* @return: com.msb.hjycommunity.community.domain.vo.HjyCommunityVo
*/
List queryPullDown(HjyCommunity community);
@Override
public List queryPullDown(HjyCommunity community) {
List dtoList = hjyCommunityMapper.queryList(community);
List voList = dtoList.stream().map(dto -> {
//对象拷贝
HjyCommunityVo communityVo = OrikaUtils.convert(dto, HjyCommunityVo.class);
return communityVo;
}).collect(Collectors.toList());
return voList;
}
//是获取caseProblemListVO实体对象的某一个属性,entry.getKey().trim() 就是某个属性的名字
Field field = caseProblemListVO.getClass().getDeclaredField(entry.getKey().trim());
//设置可赋值属性变量
field.setAccessible(true);
// 将entry.getValue() 赋值给caseProblemListVO类当前对象的属性变量
field.set(caseProblemListVO, entry.getValue());
package com.utils;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.Map;
/**
* MyBeanUtils
*
*/
/**
* 对象之间的转换工具类
*
* @see JsonUtils
*/
public class MyBeanUtils {
// 浅拷贝
/**
* shallowCopy
*
* @param source source
* @param target target
*/
public static void shallowCopy(Object source, Object target) {
BeanUtils.copyProperties(source, target);
}
/**
* 强转为List(常用于强转前端参数)
*
* @param obj 实际类型为List的Object
*/
public static List castList(Object obj) {
String json = JsonUtils.objectToJson(obj);
return JSONObject.parseObject(json, new TypeReference>(){});
}
/**
* 强转为Map(常用于强转前端参数)
*
* @param obj 实际类型为Map的Object
*/
public static Map castMap(Object obj) {
String json = JsonUtils.objectToJson(obj);
return JSONObject.parseObject(json, new TypeReference