dbutils 重写BeanProcessor 部分方法,支持enum的转换

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 type)的类 DefaultBeanProcessor extends BeanProcessor


原有toBean方法是通过数组的方式来标识column与property的关联。

  int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);

此数组中-1表示未找到相关联的,但此方法实现中使用双重循环来判断column与property相等。

由于ResultSet支持按列名字符串来查询取值。所以也放弃dbutils使用index来标识取值方式 ,使用Map来存储

protected Map columnsToPropertyMap(ResultSetMetaData rsmd,
PropertyDescriptor[] props) throws SQLException {
Map map = new HashMap();
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 toBean(ResultSet rs, Class type) throws SQLException {
PropertyDescriptor[] props = this.propertyDescriptors(type);
ResultSetMetaData rsmd = rs.getMetaData();
Map map = this.columnsToPropertyMap(rsmd, props);
return this.createBean(rs, type, props, map);
}

private T createBean(ResultSet rs, Class type,
PropertyDescriptor[] props, Map map)
throws SQLException {
T bean = this.newInstance(type);
for (Map.Entry 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 rsh = new BeanHandler<>(Bean.class, convert);
Bean bean = queryRunner.query(sql, rsh);

你可能感兴趣的:(java,技术,dbutils,jdbc)