dbutils 重写BeanProcessor 部分方法,支持enum的转换
2013-12-04 00:36
316 查看
dbutils 是apache commons下的共用封装JDBC操作的包。能直接从数据库读取转换成list,bean,map等开发常用数据类型。
它优点:包小,全部就几十个类;透明简洁;入手快,不需要创建若干对象给dbutils用。
dbutils不是OR工具,它只是简化jdbc操作,你执行sql它返回数据。
核心的三个包:
org.apache.commons.dbutils
org.apache.commons.dbutils.handlers
org.apache.commons.dbutils.wrappers
Dbutils处理连接提交关闭等操作,这是一个线程安全的。
handlers处理数据类型转换
QueryRunner查询操作
ResultSetHandler此为接口,实现转换resultSet到object(bean,map等都需要实现此接口)
XXXProcessor具体转换column到实体属性中。
BeanProcessor匹配列名bean属性名和将ResultSet column转换成对象的bean属性,但是match数据类型时,支持基本数据类型,Timestamp和SQLXML,至于其它统统作Object返回
ResultSet.getObject(index)。如果实体中定义enum,此时会出现转换异常出现。这时就需要Override
toBean(ResultSet rs, Class<T> type)的类 DefaultBeanProcessor extends BeanProcessor
原有toBean方法是通过数组的方式来标识column与property的关联。
int[]
columnToProperty = this.mapColumnsToProperties(rsmd, props);
此数组中-1表示未找到相关联的,但此方法实现中使用双重循环来判断column与property相等。
由于ResultSet支持按列名字符串来查询取值。所以也放弃dbutils使用index来标识取值方式
,使用Map<column, property>来存储
protected Map<String, PropertyDescriptor> columnsToPropertyMap(ResultSetMetaData rsmd,
PropertyDescriptor[] props) throws SQLException {
Map<String, PropertyDescriptor> map = new HashMap<String, PropertyDescriptor>();
int count = rsmd.getColumnCount();
for (int i = 1; i <= count; i++) {
String columnName = rsmd.getColumnLabel(i);
if (StringUtils.isBlank(columnName)) {
columnName = rsmd.getColumnName(i);
}
String propertyName = columnToPropertyOverrides.get(columnName);
if (propertyName == null) {
propertyName = columnName;
//删除掉字段中"_",lowcaseMapKey统一转换成小写
propertyName = StringUtils.remove(lowcaseMapKey(propertyName), "_");
}
for (PropertyDescriptor prop : props) {
String propName = prop.getDisplayName();
if (propertyName.equals(lowcaseMapKey(propName))) {
map.put(columnName, prop);
}
}
}
return map;
}
@Override
public <T> T toBean(ResultSet rs, Class<T> type) throws SQLException {
PropertyDescriptor[] props = this.propertyDescriptors(type);
ResultSetMetaData rsmd = rs.getMetaData();
Map<String, PropertyDescriptor> map = this.columnsToPropertyMap(rsmd, props);
return this.createBean(rs, type, props, map);
}
private <T> T createBean(ResultSet rs, Class<T> type,
PropertyDescriptor[] props, Map<String, PropertyDescriptor> map)
throws SQLException {
T bean = this.newInstance(type);
for (Map.Entry<String, PropertyDescriptor> entry : map.entrySet()) {
String columnName = entry.getKey();
PropertyDescriptor prop = entry.getValue();
this.callsetter(bean, prop, processorColumn(rs, columnName, prop.getPropertyType()));
}
return bean;
}
protected Object processorColumn(ResultSet rs, String label, Object propType) throws SQLException {
Object obj = rs.getObject(label);
if (rs.wasNull() || obj == null) {
return null;
}
........
if (Enum.class.isAssignableFrom((Class<?>) propType)) {//存储是int类型,若有存储name String类型此处需要修改。
int intFromDb = rs.getInt(label);
for (Object enumInstance : ((Class<?>) propType).getEnumConstants()) {
try {
int enumIndex = (int) enumInstance.getClass().getMethod("getIndex").invoke(enumInstance);
if (enumIndex == intFromDb) {
return enumInstance;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return obj;
}
调用:
String sql = "select * from table where id = "+id;
DefaultBeanProcessor bean = new DefaultBeanProcessor();
RowProcessor convert = new BasicRowProcessor(bean);
ResultSetHandler<Plan> rsh = new BeanHandler<>(Bean.class, convert);
Bean bean = queryRunner.query(sql, rsh);
它优点:包小,全部就几十个类;透明简洁;入手快,不需要创建若干对象给dbutils用。
dbutils不是OR工具,它只是简化jdbc操作,你执行sql它返回数据。
核心的三个包:
org.apache.commons.dbutils
org.apache.commons.dbutils.handlers
org.apache.commons.dbutils.wrappers
Dbutils处理连接提交关闭等操作,这是一个线程安全的。
handlers处理数据类型转换
QueryRunner查询操作
ResultSetHandler此为接口,实现转换resultSet到object(bean,map等都需要实现此接口)
XXXProcessor具体转换column到实体属性中。
BeanProcessor匹配列名bean属性名和将ResultSet column转换成对象的bean属性,但是match数据类型时,支持基本数据类型,Timestamp和SQLXML,至于其它统统作Object返回
ResultSet.getObject(index)。如果实体中定义enum,此时会出现转换异常出现。这时就需要Override
toBean(ResultSet rs, Class<T> type)的类 DefaultBeanProcessor extends BeanProcessor
原有toBean方法是通过数组的方式来标识column与property的关联。
int[]
columnToProperty = this.mapColumnsToProperties(rsmd, props);
此数组中-1表示未找到相关联的,但此方法实现中使用双重循环来判断column与property相等。
由于ResultSet支持按列名字符串来查询取值。所以也放弃dbutils使用index来标识取值方式
,使用Map<column, property>来存储
protected Map<String, PropertyDescriptor> columnsToPropertyMap(ResultSetMetaData rsmd,
PropertyDescriptor[] props) throws SQLException {
Map<String, PropertyDescriptor> map = new HashMap<String, PropertyDescriptor>();
int count = rsmd.getColumnCount();
for (int i = 1; i <= count; i++) {
String columnName = rsmd.getColumnLabel(i);
if (StringUtils.isBlank(columnName)) {
columnName = rsmd.getColumnName(i);
}
String propertyName = columnToPropertyOverrides.get(columnName);
if (propertyName == null) {
propertyName = columnName;
//删除掉字段中"_",lowcaseMapKey统一转换成小写
propertyName = StringUtils.remove(lowcaseMapKey(propertyName), "_");
}
for (PropertyDescriptor prop : props) {
String propName = prop.getDisplayName();
if (propertyName.equals(lowcaseMapKey(propName))) {
map.put(columnName, prop);
}
}
}
return map;
}
@Override
public <T> T toBean(ResultSet rs, Class<T> type) throws SQLException {
PropertyDescriptor[] props = this.propertyDescriptors(type);
ResultSetMetaData rsmd = rs.getMetaData();
Map<String, PropertyDescriptor> map = this.columnsToPropertyMap(rsmd, props);
return this.createBean(rs, type, props, map);
}
private <T> T createBean(ResultSet rs, Class<T> type,
PropertyDescriptor[] props, Map<String, PropertyDescriptor> map)
throws SQLException {
T bean = this.newInstance(type);
for (Map.Entry<String, PropertyDescriptor> entry : map.entrySet()) {
String columnName = entry.getKey();
PropertyDescriptor prop = entry.getValue();
this.callsetter(bean, prop, processorColumn(rs, columnName, prop.getPropertyType()));
}
return bean;
}
protected Object processorColumn(ResultSet rs, String label, Object propType) throws SQLException {
Object obj = rs.getObject(label);
if (rs.wasNull() || obj == null) {
return null;
}
........
if (Enum.class.isAssignableFrom((Class<?>) propType)) {//存储是int类型,若有存储name String类型此处需要修改。
int intFromDb = rs.getInt(label);
for (Object enumInstance : ((Class<?>) propType).getEnumConstants()) {
try {
int enumIndex = (int) enumInstance.getClass().getMethod("getIndex").invoke(enumInstance);
if (enumIndex == intFromDb) {
return enumInstance;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return obj;
}
调用:
String sql = "select * from table where id = "+id;
DefaultBeanProcessor bean = new DefaultBeanProcessor();
RowProcessor convert = new BasicRowProcessor(bean);
ResultSetHandler<Plan> rsh = new BeanHandler<>(Bean.class, convert);
Bean bean = queryRunner.query(sql, rsh);
相关文章推荐
- vue填坑之解决部分浏览器不支持pushState方法
- C#部分---arraylist集合、arraylist集合中的object数据转换成int类string类等;间隔时间的表示方法;
- “该程序集不支持部分受信任的调用方”的解决方法
- [方法“Boolean Contains(System.Guid)”不支持转换为 SQL]的解决办法
- DBUtils – BeanProcessor扩展,支持自定义字段映射
- php 五种数据加密可解密方法,部分还支持中文
- hibernate将hql转换成count(*)的方法,支持所有的数据库oracle,mysql等
- ASP.NET.MVC--注解和反射将Enum转换List<SelectListItem>为@Html.DropDownListFor()下拉列表的通用方法
- 【C语言】任意进制之间的转换(支持小数部分)
- 继承和方法重写如何支持多态性
- [方法“Boolean Contains(System.Guid)”不支持转换为 SQL]的解决办法
- struts2的action支持自动转换枚举类型(enum)的实例变量
- 关于Android WebView不支持location.href打开的解决方法 小米部分机型
- DBUtils – BeanProcessor扩展,支持自定义字段映射
- java :引用类型的转换  方法重载和重写  构造函数 修饰符
- 让BeanUtils的copyProperty方法支持String与java.util.Date的类型转换
- 在MVC的WebApi中默认是没有开启Session会话支持的。需要在Global中重写Init方法来指定会话需要支持的类型
- 让Apache支持Rewrite静态页面重写的方法
- JAVA隐式转换和方法重写和static关键字
- 移植u-boot-2011.03到S3C2440(utu2440)的方法与步骤###7.NAND FLASH部分移植和支持NAND FLASH启动和读写