zoukankan      html  css  js  c++  java
  • BeanListHandler

    BeanListHandler 是可供DBUtils查询器使用的一个Handler类,它的作用是将查询结果转换为一个列表。列表中元素为查询结果所转换的JavaBean,Bean的类型为开发者所指定的Class。参考如下这段代码:
    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 &lt;= cols; col++) {
                            String columnName = rsmd.getColumnLabel(col);
                            if (null == columnName || 0 == columnName.length()) {
                                    columnName = rsmd.getColumnName(col);
                            }
                            for (int i = 0; i &lt; 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()));
     
     
  • 相关阅读:
    1024X768大图 (Wallpaper)
    (Mike Lynch)Application of linear weight neural networks to recognition of hand print characters
    瞬间模糊搜索1000万基本句型的语言算法
    单核与双核的竞争 INTEL P4 670对抗820
    FlashFTP工具的自动缓存服务器目录的功能
    LDAP over SSL (LDAPS) Certificate
    Restart the domain controller in Directory Services Restore Mode Remotely
    How do I install Active Directory on my Windows Server 2003 server?
    指针与指针变量(转)
    How to enable LDAP over SSL with a thirdparty certification authority
  • 原文地址:https://www.cnblogs.com/datapool/p/6817936.html
Copyright © 2011-2022 走看看