巴拉巴拉
小魔仙

BeanFly-Map类型转对象

今天打算写一个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) ==> 是类型转对象的判断

赞(0) 打赏
如果文章对你有帮助,欢迎你来评价反馈。AgainFly » BeanFly-Map类型转对象
标签:

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  • Q Q(选填)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏