Map 与 JavaBean 的相互装换
目的
为了方便使用 DbUtils,在插入数据时需要传入含有占位符的 SQL 语句和对应占位符的值(数组),封装代码如下:
/** * 插入实体 */ public static <T> Long insertEntity(Class<T> entityClass, Map<String, Object> fieldMap) { if (CollectionUtil.isEmpty(fieldMap)) { LOGGER.error("can not insert entity: fieldMap is empty"); return null; } String sql = "INSERT INTO " + getTableName(entityClass); StringBuilder colums = new StringBuilder("("); StringBuilder values = new StringBuilder("("); // 插入实体的字段名,和字段值的占位符 for (String colum : fieldMap.keySet()) { colums.append(colum).append(", "); values.append("?, "); } colums.replace(colums.lastIndexOf(", "), colums.length(), ")"); values.replace(values.lastIndexOf(", "), values.length(), ")"); sql += colums + " VALUES " + values; // 插入实体的值 Object[] params = fieldMap.values().toArray(); Long result = null; try { result = QUERY_RUNNER.insert(sql, new ScalarHandler<Long>(), params); } catch (SQLException e) { LOGGER.error("insert failed : {}", e); } return result; }
调用该方法需要将JavaBean转化成Map<Key, Value>的形式,那不如提供一个JavaBean与Map的装换工具类。
Mybatis 源码中应该也有这种转换过程。
实现
package org.snowflake.framework.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; /** * Map 与 JavaBean 的相互转换 * Created by zhengbinMac on 2017/4/24. */ public class BeanUtil { private static final Logger LOGGER = LoggerFactory.getLogger(BeanUtil.class); public static void transMap2Bean(Map<String, Object> map, Object obj) { try { BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] propertyDescriptor = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pro : propertyDescriptor) { String key = pro.getName(); if (map.containsKey(key)) { Object value = map.get(key); Method method = pro.getWriteMethod(); method.invoke(obj, value); } } } catch (Exception e) { LOGGER.error("transMap2Bean failed, Exception: {}", e); } } public static Map<String, Object> tranBean2Map(Object obj) { if (obj == null) { return null; } Map<String, Object> resultMap = new HashMap<String, Object>(); try { BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pro : propertyDescriptors) { String key = pro.getName(); if (!key.equals("class")) { // 过滤 class 的属性 // 得到property对应的getter方法 Method method = pro.getReadMethod(); Object value = method.invoke(obj); resultMap.put(key, value); } } } catch (Exception e) { LOGGER.error("tranBean2Map failed, Exception: {}", e); } return resultMap; } }
测试类:
package com.wxct.test.dao; import com.wxct.model.Person; import org.snowflake.framework.util.BeanUtil; import java.util.Map; /** * Created by zhengbinMac on 2017/4/24. */ public class BeanUtilTest { public static void main(String[] args) { Person p1 = new Person(); p1.setId(201370034217L); p1.setName("郑斌"); Map<String, Object> map = BeanUtil.tranBean2Map(p1); System.out.println(map); Person p2 = new Person(); BeanUtil.transMap2Bean(map, p2); System.out.println(p2); } }
测试结果:
{name=郑斌, id=201370034217}
Person{id=201370034217, name='郑斌'}
反射实现
通过 java.lang.reflect 下的 Field 实现:
public static Map<String, Object> beanToMap(Object obj) { Map<String, Object> resultMap = new HashMap<String, Object>(); Class cls = obj.getClass(); Field[] fields = cls.getDeclaredFields(); // 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。 try { for (Field field : fields) { field.setAccessible(true); resultMap.put(field.getName(), field.get(obj)); } } catch (Exception e) { LOGGER.error("mapToBean failed, Exception: ", e); } return resultMap; } public static void mapToBean(Map<String, Object> map, Object obj) { try { Class cla = obj.getClass(); for (String key : map.keySet()) { Field field = cla.getDeclaredField(key); field.setAccessible(true); field.set(obj, map.get(key)); } } catch (Exception e) { LOGGER.error("mapToBean failed, Exception: ", e); } }
通过测试,反射的方式相比上一种更加的高效。
参考资料
[1] javaBean与Map<String,Object>互转
[2] 基于java反射的javabean和map相互转换的工具类
梦想要一步步来!