BeanListHandler
2014-06-09 12:48
106 查看
BeanListHandler 是可供DBUtils查询器使用的一个Handler类,它的作用是将查询结果转换为一个列表。列表中元素为查询结果所转换的JavaBean,Bean的类型为开发者所指定的Class。参考如下这段代码:
查询结果每一行都会自动转换为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方法。
总结一下调用次序:
原来BeanProcessor.toBeanList是完成这个转换的关键,映射规则的处理机制就藏在这里。
BeanProcessor.toBeanList的实现机理,大致是以下几个步骤
至此我们了解了整个转换过程,解决方案也相应而生。以BeanProcessor作为父类,实现一个自定义的BeanProcessor子类,并使用自定义的mapColumnsToProperties方法覆盖父类的方法。代码如下:
public Template[] list(Connection conn, String owner, String catagory) { String sql; QueryRunner runner = new QueryRunner(); BeanListHandler<Template> handler = new BeanListHandler<Template>(Template.class); sql = "SELECT * FROM GEN_TEMPLATE WHERE OWNER = ? AND CATAGORY = ?"; try { List<Template> aList = runner.query(conn, sql, handler, new Object[] { 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方法覆盖父类的方法。代码如下:
import java.beans.PropertyDescriptor; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.Arrays; import org.apache.commons.dbutils.BeanProcessor; /** * æ�©å±�BeanProcessorç��å¤�ç��æ�¹å¼�ï¼�使å�¶è�½å¤�å¤�ç��å¦�DATA_OBJECT_NAME -> dataObjectNameè¿�æ ·ç��æ� å°�å�³ç³» */ public class GenBeanProcess extends BeanProcessor { /** * æ�¿æ�¢BeanProcessorç��æ� å°�å�³ç³»å¤�ç�� */ @Override protected int[] mapColumnsToProperties(ResultSetMetaData rsmd, PropertyDescriptor[] props) throws SQLException { 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; } } } return columnToProperty; } /** * DATA_OBJECT_NAME -> dataObjectName */ private String convert(String objName) { StringBuilder result = new StringBuilder(); String[] tokens = objName.split("_"); for (String token : tokens) { if (result.length() == 0) result.append(token.toLowerCase()); else result.append(StringUtils.capitalize(token.toLowerCase())); } return result.toString(); } }
// å��å°�å¼�å¤´æ ·ä¾�ä¸ç��è¿�å�¥ BeanListHandler<Template> handler = new BeanListHandler<Template>(Template.class); // æ�¿æ�¢ä¸º BeanListHandler<Sql> handler = new BeanListHandler<Sql>(Template.class, new BasicRowProcessor(new GenBeanProcess()));
相关文章推荐
- 常用结果集 scalarHandler,beanListHandler,BeanHander ,columnlistHandler,BeanMapHandler,ArrayHandler
- BeanListHandler演示
- BeanListHandler:(常用)将多条记录封装到一个装有JavaBean的List集合中;MapHandler: 将一条记录封装到一个Map集合中,Map的key是列名,Map的value就是
- 今天在使用commons-dbutils时的,BeanListHandler处理赋值,有些值为空的错误
- dbutils使用---QueryRunner、BeanListHandler、BeanHandler、MapListHandler、MapHandler、ScalarHandler
- 关于 BeanListHandler的用法
- 结果集的第四种处理方法BeanListHandler
- JDBC和DBUtils区别(查询时jdbc只能返回ResultSet需要po转vo,dbutils返回的BeanListHandler与BeanHandler对应集合与对象)
- dbutils使用---QueryRunner、BeanListHandler、BeanHandler、MapListHandler、MapHandler、ScalarHandler
- httpHandler实现.Net无后缀名Web访问的实现解析
- Android中Handler小例子
- Android_非UI:倒计时 Handler + Timer + CounDownTimer
- Message,MessageQueue,Looper,Handler详解+实例
- ASP.NET利用HttpHandler实现多扩展名文件下载
- Netty内部组件 in out bound handler等
- Handler分析
- Android中Handler原理
- Android Handler 内存泄漏
- 在Android中使用Handler和Thread线程执行后台操作
- Android中Handler Runnable与Thread的区别详解