java beanlisthandler_BeanListHandler

BeanListHandler 是可供DBUtils查询器使用的一个Handler类,它的作用是将查询结果转换为一个列表。列表中元素为查询结果所转换的JavaBean,Bean的类型为开发者所指定的Class。参考如下这段代码:

publicTemplate[] list(Connection conn, String owner, String catagory) {

String sql;

QueryRunner runner= newQueryRunner();

BeanListHandler<Template> handler = new BeanListHandler<Template>(Template.class);

sql= "SELECT * FROM GEN_TEMPLATE WHERE OWNER = ? AND CATAGORY = ?";try{

List aList = runner.query(conn, sql, handler, newObject[] { owner, catagory });return aList.toArray(new Template[0]);

}catch(Exception ex) {throw new GenException(ex, "读���模��表�����常�");

}

}

查询结果每一行都会自动转换为Template类的实例,并且装进List作为结果返回。缺省的查询字段与JavaBean的属性匹配规则是忽略大小写后的字符完全匹配。

通常,数据库的字段往往会出现2个单词以上的情况,比如TEMPLATE_ID这个字段名,以下划线作为分隔。对应的JavaBean的属性名,按照Java的命名规范(驼峰原则),则是templateId。这种情况下,BeanListHandler就无法做TEMPLATE_ID->templateId的映射了。对于这样的问题,有一种解决办法就是给查询结果的显示字段取别名,如TEMPLATE_ID AS templateId。在字段较少的情况下,这个办法可以作为权益之计。但是,字段较多的时候,这种办法就显得很笨拙了。

另外一种想法,就是BeanListHandler能够做TEMPLATE_ID->templateId的映射。

那么如何使BeanListHandler按照我们的要求做映射呢?打开DBUtils的源代码,来看下它的内在处理机制。

BeanListHandler通过handle方法处理查询结果ResultSet的实例,并返回最终的List实例。handle方法使用RowProcessor作为ResultSet->BeanList的转换器,调用它的toBeanList方法完成转换。缺省情况下,BeanListHandler所使用的RowProcessor为ArrayHandler的缺省RowProcessor,其类型是BasicRowProcessor。缺省情况下,BasicRowProcessor使用BeanProcessor作为转换器,调用它的toBeanList方法。

总结一下调用次序:

BeanListHandler.handle->BasicRowProcessor.toBeanList->BeanProcessor.toBeanList

原来BeanProcessor.toBeanList是完成这个转换的关键,映射规则的处理机制就藏在这里。

BeanProcessor.toBeanList的实现机理,大致是以下几个步骤

1. 循环处理ResultSet每一行记录

1.1 得到JavaBean的属性集合

1.2 得到ResultSet的元数据集合

1.3 调用mapColumnsToProperties方法,得到以上2者的映射关系索引集

1.4 创建JavaBean的实例,并根据1.3得到的索引集,完成行的值到JavaBean属性的注入

至此我们了解了整个转换过程,解决方案也相应而生。以BeanProcessor作为父类,实现一个自定义的BeanProcessor子类,并使用自定义的mapColumnsToProperties方法覆盖父类的方法。代码如下:

importjava.beans.PropertyDescriptor;importjava.sql.ResultSetMetaData;importjava.sql.SQLException;importjava.util.Arrays;importorg.apache.commons.dbutils.BeanProcessor;/*** æ�©å±�BeanProcessorç��å¤�ç��æ�¹å¼�ï¼�使å�¶è�½å¤�å¤�ç��å¦�DATA_OBJECT_NAME -> dataObjectNameè¿�æ ·ç��æ� å°�å�³ç³»*/

public class GenBeanProcess extendsBeanProcessor {/*** æ�¿æ�¢BeanProcessorç��æ� å°�å�³ç³»å¤�ç��*/@Overrideprotected int[] mapColumnsToProperties(ResultSetMetaData rsmd, PropertyDescriptor[] props) throwsSQLException {int cols =rsmd.getColumnCount();int[] columnToProperty = new int[cols + 1];

Arrays.fill(columnToProperty, PROPERTY_NOT_FOUND);for (int col = 1; col <= cols; col++) {

String columnName=rsmd.getColumnLabel(col);if (null == columnName || 0 ==columnName.length()) {

columnName=rsmd.getColumnName(col);

}for (int i = 0; i < props.length; i++) {if(convert(columnName).equals(props[i].getName())) {

columnToProperty[col]=i;break;

}

}

}returncolumnToProperty;

}/*** DATA_OBJECT_NAME -> dataObjectName*/

privateString convert(String objName) {

StringBuilder result= newStringBuilder();

String[] tokens= objName.split("_");for(String token : tokens) {if (result.length() == 0)

result.append(token.toLowerCase());elseresult.append(StringUtils.capitalize(token.toLowerCase()));

}returnresult.toString();

}

}//å��å°�å¼�å¤´æ ·ä¾�中ç��è¿�å�¥

BeanListHandler handler = new BeanListHandler(Template.class);//��为

BeanListHandler handler = new BeanListHandler(Template.class, new BasicRowProcessor(new GenBeanProcess()));

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值