目的

为了方便使用 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相互转换的工具类

Map 与 JavaBean 的相互装换的更多相关文章

  1. int和string的相互装换 (c++)

    int和string的相互装换 (c++) int转换为string 第一种方法 to_string函数,这是c++11新增的函数 string to_string (int val); string ...

  2. [CSAPP笔记]Binary , Unsigned , Signed 之间的相互装换

    LaTex+MarkDown+Pandoc组合套件写博客的处女作,试试效果.各自的分工为:Latex下编辑公式,在Sublime Text 2下使用Markdown排版,最后用Pandoc导出. 摘要 ...

  3. DOM对象 与 jQuery对象 之间的相互装换

    示例代码: //jQuery对象转DOM对象 //因为jQuery对象是一个数组对象,所以转换为DOM对象时要用索引的形式 var $div1 = $("#div1"); //jQ ...

  4. xml与java代码相互装换的工具类

    这是一个java操作xml文件的工具类,最大的亮点在于能够通过工具类直接生成xml同样层次结构的java代码,也就是说,只要你定义好了xml的模板,就能一键生成java代码.省下了自己再使用工具类写代 ...

  5. python基础知识-集合,列表,元组间的相互装换

    在python中列表,元祖,集合间可以进行相互转化, def main(): set1={'hello','good','banana','zoo','Python','hello'} print(l ...

  6. opencv之深拷贝及浅拷贝,IplImage装换为Mat

    一.(1)  浅拷贝: Mat B; B = image  // 第一种方式 Mat C(image); // 第二种方式 这两种方式称为浅copy,是由于它们有不同的矩阵头,但是它们共享内存空间,即 ...

  7. 【计算机视觉】【图像处理】【VS开发】【Qt开发】opencv之深拷贝及浅拷贝,IplImage装换为Mat

    原文:opencv之深拷贝及浅拷贝,IplImage装换为Mat  一.(1) 浅拷贝: Mat B; B = image // 第一种方式 Mat C(image); // 第二种方式 这两种方式称 ...

  8. C# DataSet装换为泛型集合

    1.DataSet装换为泛型集合(注意T实体的属性其字段类型与dataset字段类型一一对应) #region DataSet装换为泛型集合 /// <summary> /// 利用反射和 ...

  9. oracle中的装换函数

    日期装换成字符的函数:TO_CHAR(date[,fmt[,params]]) 默认格式:DD-MON-RR 参数说明: date:将要装换的日期 fmt:装换的格式 params:日期的语言(可以不 ...

随机推荐

  1. 《JAVA与模式》之原型模式(转载)

    原型模式其实就是java的拷贝机制 原文出处:http://blog.csdn.net/zhengzhb/article/details/7393528   定义:用原型实例指定创建对象的种类,并通过 ...

  2. Internet上的WWW服务与HTTP协议(非常非常不错的文档,推荐订阅)

    Internet上的WWW服务与HTTP协议 兼容性----H1TP/1.1与HTTP/1.0后向兼容;运行1.1版本的web服务器可以与运行1.0版本的浏览器“对话”,运行1.1版本的浏览器也可以与 ...

  3. Java 8 – Stream Collectors groupingBy count examples

    Java 8 – Stream Collectors groupingBy count examples 1. Group By, Count and Sort1.1 Group by a List ...

  4. es5 温故而知新 创建私有成员、私有变量、特权变量的方法

    其实js是不支持私有变量的.哪怕到es6的class语法.虽然有许多变相的方式.但非常冗余而不推崇. 这里介绍的实际上也不是class语法,而是普通的函数,并且利用IIFE(闭包)的方式来实现私有. ...

  5. flock防止crontab脚本周期内未执行完重复执行(转)

    如果某脚本要运行30分钟,可以在Crontab里把脚本间隔设为至少一小时来避免冲突.而比较糟的情况是可能该脚本在执行周期内没有完成,接着第二个脚本又开始运行了.如何确保只有一个脚本实例运行呢?一个好用 ...

  6. iframe父页面获取iframe子页面的元素 与 iframe子页面获取父页面元素

    一.在iframe子页面获取父页面元素代码如下:$('#objld', parent.document); 二.在父页面获取iframe子页面的元素代码如下:$("#objid", ...

  7. IOS 缓存方案(按需缓存 、 预缓存)及 低网速模拟

    1,在设备中 设置开发者模式. 参照上面设置 自定义 添加.丢包率 35. 或者参照这个文章:http://ivoryxiong.org/devops/2013/05/24/ios_dev_handl ...

  8. IOS 程序员开发最常用宏定义

    网上对IOS的宏定义比较多,我总结了一些最常用的宏,后续还会继续补上. 1.首次启动判断: #define First_Launched @"firstLaunch" 2.ios7 ...

  9. IOS使用AVAudioPlayer播放mp3歌曲文件并监听来电打断

    本实例实现了AVAudioPlayer播放mp3歌曲文件,实现了播放.暂停.继续操作,音乐音量控制.播放进度显示,同时监听来电打断事件 一.控件初始化 - (void)viewDidLoad { [s ...

  10. Filberder教程

    http://www.cnblogs.com/TankXiao/archive/2012/02/06/2337728.html