今天打算写一个jdbc的demo,但是发现要一个一个对对象进行set很麻烦,于是想干脆弄一个map吧,然后要吧map转为对象,有一个工具是BeanUtils,可以很方便的将一个map之类的转换成一个对象,但是必须map中的key和对象中的字段名完全一致,否则设置不进去。
于是就自己写了一个简单的转换工具类,根据网站名againfly,所以工具类名BeanFly。
在数据库中,并没有大小写这一说,我们可以大写,可以小写,甚至可以大小写混写,都是可以的。
但是对于java就必须严谨了,因为是严格进行大小写区分的。
嗯。。。。就是刚刚整理代码的时候,,,发现有更简单的实现。。。代码删掉重写了=。=
现在更简单了,不过等下注意一个小知识点吧,放在文章的最后介绍吧——Class<?>.isInstance(Object obj)方法
不过首先的还是要介绍本文东西,将Map转为Bean对象。
如同介绍一样,最简单的方法其实是使用BeanUtils工具类,由commons提供,不过必须map中的key和字段名完全匹配才能进行值设置。
先放出演示:
public class CustInfo { private int id; private String custName; private Date time; /* 省略getter,setter,toString方法 */ }
/* **********************字段不区分大小写************************ */ Map<Object, Object> obj = new HashMap<>(); obj.put("id", 1); obj.put("cUsTnAmE", "用户名"); obj.put("TIme", new Date()); CustInfo ci = BeanFly.Map2BeanIgnoreCase(obj, CustInfo.class); System.out.println(ci); /* **********************字段区分大小写************************ */ Map<Object, Object> obj2 = new HashMap<>(); obj2.put("id", 2); obj2.put("custName", "custname"); obj2.put("time", new Timestamp(System.currentTimeMillis())); ci = BeanFly.Map2Bean(obj2, CustInfo.class); System.out.println(ci);
执行效果:
CustInfo [id=0, custName=用户名, time=Tue Jan 17 16:28:26 CST 2017] CustInfo [id=0, custName=custname, time=2017-01-17 16:28:26.315]
这里有两个方法,是因为如果能区分大小写进行转换的话还是区分后转换吧,毕竟效率高。如果不区分大小写的话会遍历所有字段进行匹配,效率肯定是有点影响的。
先晒出整合类,虽然不是具体实现类,但是看上去更清晰明了,也为了方便未来可能会加入Xml2Bean之类的东东。
package com.againfly.util; import java.util.Map; public class BeanFly { /** * map对象转对象,需要map对象中的key和对象字段名称大小写完全对应, * 效率高 */ public static <T> T Map2Bean(Map<Object, Object> map, Class<T> clazz) { return MapBeanConvert.Map2Bean(map, clazz, true); } /** * map对象转对象,map中的key可以大小写不完全对应,效率略低 */ public static <T> T Map2BeanIgnoreCase(Map<Object, Object> map, Class<T> clazz){ return MapBeanConvert.Map2Bean(map, clazz, false); } }
=-================================================
具体的转换实现方法
要求转换的对象必须要有默认的构造方法
1.遍历map中的entity
2.根据flag来确定如何获取Field字段
flag:true
根据entity中的key,进行完全匹配找到对应的字段
flag: false
遍历对象中所有字段,进行字段名判断,如果有一致的就获取这个字段Field
3.根据PropertyDescriptor获取相应字段的set写入方法
4.执行该写入方法==>如果抛出异常全部忽略跳过
package com.againfly.util; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; public class MapBeanConvert { public static <T> T Map2Bean(Map<Object, Object> map, Class<T> clazz, boolean flag){ T obj = null; try { obj = clazz.newInstance(); } catch (InstantiationException | IllegalAccessException e) { System.err.println(clazz.getName() + "没有默认的构造方法"); return obj; } for(Map.Entry<Object, Object> entrty : map.entrySet()){ Field field = null; if(flag){ try { field = clazz.getDeclaredField(entrty.getKey().toString()); } catch (NoSuchFieldException | SecurityException e) { e.printStackTrace(); } }else { for (Field _field : clazz.getDeclaredFields()) { if (_field.getName().equalsIgnoreCase(entrty.getKey().toString())) { field = _field; } } } if(null != field && field.getType().isInstance(entrty.getValue())){ PropertyDescriptor pd; try { pd = new PropertyDescriptor(field.getName(), clazz); Method setMethod = pd.getWriteMethod(); setMethod.invoke(obj, entrty.getValue()); } catch (IntrospectionException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } } } return obj; } }
======================================================
来,最后说一下Class<?>.isInstance(Object obj)方法
java当中有个运算符是instanceof
System.out.println(new Timestamp(0) instanceof Date);
//输出true
可以判断一个对象是否能转换成另一种类型
而同样的isInstance方法则是判断一个类型是否能转为某个对象
System.out.println( Date.class.isInstance(new Timestamp(0)) );
//输出true
所以,理论上instanceof判断为true的地方,使用isInstance判断也是true
简单的来说
obj instanceof Object ==> 是对象转类型的判断
Class<?>.isInstance(obj) ==> 是类型转对象的判断
最新评论