业务场景: 设计规范前提下,我们数据层传输承载的是用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, Class targetClass) {
return convert(sourceEntity, targetClass, null);
}
/**
* 字段不一致实体转换函数(需要字段映射)
* @param sourceEntity 源实体
* @param targetClass 目标类对象
* @param refMap 配置源类与目标类不同字段名映射
* @param 源泛型
* @param 目标泛型
* @return 目标实体
*/
public static T convert(S sourceEntity, Class targetClass, 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 List convertList(List sourceEntityList, Class targetClass) {
return convertList(sourceEntityList, targetClass, null);
}
/**
* 字段不一致集合转换函数 (需要字段映射)
*
* @param sourceEntityList 源实体集合
* @param targetClass 目标类对象
* @param refMap 配置源类与目标类不同字段名映射
* @param 源泛型
* @param 目标泛型
* @return 目标实体集合
*/
public static List convertList(List sourceEntityList, Class targetClass, 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