您的位置:首页 > 其它

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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐