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
原有toBean方法是通过数组的方式来标识column与property的关联。
int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);
此数组中-1表示未找到相关联的,但此方法实现中使用双重循环来判断column与property相等。
由于ResultSet支持按列名字符串来查询取值。所以也放弃dbutils使用index来标识取值方式 ,使用Map
protected Map
PropertyDescriptor[] props) throws SQLException {
Map
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
PropertyDescriptor[] props = this.propertyDescriptors(type);
ResultSetMetaData rsmd = rs.getMetaData();
Map
return this.createBean(rs, type, props, map);
}
private
PropertyDescriptor[] props, Map
throws SQLException {
T bean = this.newInstance(type);
for (Map.Entry
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
Bean bean = queryRunner.query(sql, rsh);