Map集合转为实体对象
Map集合转为实体对象源码:https://gitee.com/Jakewabc/small-study-case/blob/master/nm-demo/mongodb-demo/src/main/java/com/mongodb/utils/ObjectIdJsonSerializer.java使用MongoDB朋友都明白,如果我们使用连集合查询的时候需要使用聚合。但是聚合查询有个特点,我们实
Map集合转为实体对象
使用MongoDB
朋友都明白,如果我们使用连集合查询的时候需要使用聚合。但是聚合查询有个特点,我们实体类里面的 id
字段会保存在MongoDB
中会做 _id
。但是如果使用聚合查询时,返回给我们的字段依然是 _id
而不是 id
。但是返回来的是一个Map
集合,从表我们可以根据自己定义的kay
直接从Map
集合中获取做一个强转是没有问题的。但是主表有多少个字段就在MongoDB
返回的这个Map
集合中就有多少个key
。总不能让我们一个字段一个字段的去取出来存入对象吧,所以使用反射写一个工具类,直接调用即可将Map
集合转为实体对象。
package com.centre.common.utils;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 将Map集合转为对象
* <p>
* 使用范例:
* public static void main(String[] args) throws Exception {
* Map<String,Object> map = new HashMap<>();
* map.put("id",12346546l);
* map.put("name","比亚迪,长安");
* map.put("manufactor","比亚迪厂家,长安厂家");
* map.put("dateOfManufacture",new Date());
*
* HandleMapToObject<CarDO> toObject = new HandleMapToObject<CarDO>();
* CarDO carDO = toObject.mapToObject(map, CarDO.class,true);
* System.out.println(carDO);
* // 输出结果:CarDO(id=12346546, name=比亚迪,长安, manufactor=比亚迪厂家,长安厂家, dateOfManufacture=Thu Mar 11 00:41:32 CST 2021)
* }
* </p>
* @Author: Stars
* @Date: 2021/3/10 22:06
*/
public class HandleMapToObject<T> {
/**
* 将Map集合转为实体对象
* @param map Map集合
* @param t 转换后的对象
* @param considerThread true:考虑现成安全,false:不考虑
* @return
* @throws Exception
*/
private T mapToObject(Map map, Class<T> t,Boolean considerThread) throws Exception {
Class<?> clazz = null;
if (considerThread) {
//通过类装载器获取t类对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
clazz = loader.loadClass(Class.forName(t.getName()).getName());
} else {
clazz = Class.forName(Class.forName(t.getName()).getName());
}
//获取类的默认构造器对象并通过它实例化t
Constructor cons = clazz.getDeclaredConstructor((Class[]) null);
T t1 = (T) cons.newInstance();
// 获取t对象的所有属性
Field[] fields = clazz.getDeclaredFields();
// 将t对象中属性保存为Map的key值,数据类型保存为value值
Map<String, Object> fieldMap = Arrays.stream(fields).collect(Collectors.toMap(Field::getName, Field::getType));
// 取出map集合中的全部数据
Class<?> finalClazz = clazz;
map.forEach((k, v) -> {
try {
// 给当前属性赋值,本来数据类型应该fieldMap.get(k).getClass()这样写。但是上面获取t对象的数据类型时Field::getType这种方法应用不能再获取getName()属性,所以这里是class java.lang.String的类型了,不能再点getClass()了。 所有强转了一下。(Class) fieldMap.get(k)
Method setBrand = finalClazz.getMethod(initcap(String.valueOf(k)), (Class) fieldMap.get(k));
setBrand.invoke(t1, v);
} catch (Exception e) {
System.out.println("map集合转数组异常:"+t.getClass());
}
});
return t1;
}
/***
* 将对象属性转为set方法名
* @param str 转大写的字符串
* @return
*/
public static String initcap(String str) {
return "set" + str.substring(0, 1).toUpperCase() + str.substring(1) ;
}
}
- 实现思路
将Map
集合名为为map
和实体对象类型传入。创建一个Map
集合保存对象的属性和数类型,Map
集合名为fieldMap
,因为反射赋值时需要使用对象属性和属性类型。将对象的属性保存为fieldMap
集合的key
,数据类型保存为fieldMap
集合的value
。然后循环map
集合,因为MongoDB
返回来的这个map
集合的key
就是对象的属性名。所以循环map
集合,取出key
值到fieldMap
集合中获取数类型。现在属性名、数据类型和保存的数据都知道了,接下来的事情就是水到渠成了。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)