日期:2014-05-16  浏览次数:20460 次

Commons DbUtils 源码阅读七

? 实际上,我们也知道官网上对ResultSet的解析示例:

?

// 创建一个ResultSetHandler的实现类
//以实现将第一行转换为一个Object[]
ResultSetHandler<Object[]> h = new ResultSetHandler<Object[]>() {
    public Object[] handle(ResultSet rs) throws SQLException {
        if (!rs.next()) {
            return null;
        }
    
        ResultSetMetaData meta = rs.getMetaData();
        int cols = meta.getColumnCount();
        Object[] result = new Object[cols];

        for (int i = 0; i < cols; i++) {
            result[i] = rs.getObject(i + 1);
        }

        return result;
    }
};

// 使用指定数据源的一个数据连接实例,
// 创建一个QueryRunner实例。
QueryRunner run = new QueryRunner(dataSource);

// 执行查询,通过ResultSetHandler的实现类对象h实例获取到结果
Object[] result = run.query(
    "SELECT * FROM Person WHERE name=?", h, "John Doe");

?

通过何种方式创建QueryRunner实例,这个咱就不看了吧(new QueryRunner(con))。重点看ResultSetHandler的实现类,看到了吧,自己实现ResultSetHandler以达到ResultSetHandler到Object[]的转换,如果我要转换List、Map等各种形式,那我岂不是又要自己实现巨多的ResultSetHandler子对象了嘛!灵活性,很高;难度,也不差。幸好,handlers包中已经有了各种ResultSet类型转换的实现了,耶~所以,今天来拜读一下!

? 1)ScalarHandler :将一个ResultSet指定的列转换为一个对象

?

    /**
     * 指定的列号
     */
    private final int columnIndex;

    /**
     * 指定的列名,列名和列号是鱼和熊掌不可兼得
   */
    private final String columnName;

    /** 
     * 创建一个ScalarHandler实例,默认列号1
     */
    public ScalarHandler() {
        this(1, null);
    }

    /** 
     * 创建一个ScalarHandler对象
     * @param columnIndex 列号,获取指定列号的ResultSet值
   */
    public ScalarHandler(int columnIndex) {
        this(columnIndex, null);
    }

    /** 
     * 创建一个ScalarHandler对象
     * @param columnName 列名,获取此指定列名的ResultSet值
     */
    public ScalarHandler(String columnName) {
        this(1, columnName);
    }

    /** 帮助类构造器
     * @param columnIndex 列号,获取指定列号的ResultSet值
       * @param columnName 列名,获取此指定列名的ResultSet值 从ResultSet中返回
       */
    private ScalarHandler(int columnIndex, String columnName){
        this.columnIndex = columnIndex;
        this.columnName = columnName;        
    }

    /**
     * 通过ResultSet.getObject()方法,返回指定列名或列号的对象
     */
    public Object handle(ResultSet rs) throws SQLException {

        if (rs.next()) {
            if (this.columnName == null) {
                return rs.getObject(this.columnIndex);
            } else {
                return rs.getObject(this.columnName);
            }

        } else {
            return null;
        }
    }

??? 看最后的handle(ResultSet rs)方法,它首先呢,会选择使用指定的列名来获取指定的值,如果没有,则会用列号获取值。看起来,相当的简单。

?? 2)ArrayHandler :转换一个指定ResultSet行为一个Object[]

?

    /**
       * RowProcessor的单实例,被handlers包共享。
     * 注意:默认的使用范围,仅被handlers包中的类实例所共享
     */    
       static final RowProcessor ROW_PROCESSOR = new BasicRowProcessor();

    /**
     *将第一行的列值存放在Object[]数组中并返回,
   * 结果为空则返回null
     */
    public Object[] handle(ResultSet rs) throws SQLException {
        return rs.next() ? this.convert.toArray(rs) : null;
    }

???将ResultSet的行交由BasicRowProcessor实例的toArray()方法去完成Object[]的转换工作,ROW_PROCESSOR常量被handlers包下的多个ResultSetHandler实现类所共享。

??3)MapHandler :?转换第一个ResultSet的行集为一个Map对象返回

?

    /** 
      * 创建MapHandler实例
    * 默认使用BasicRowProcessor实例    
      */
    public MapHandler() {
        this(ArrayHandler.ROW_PROCESSOR);
    }

    /**
     * 将ResultSet中的第一行转换为一个Map集合并返回
     */
    public Map<String,Object> handle(ResultSet rs) throws SQLException {
        return rs.next() ? this.convert.toMap(rs) : null;
    }

?? ArrayHandler声明的一个默认行处理器,哝,现在立刻使用到了,当然了,你也可以实现RowProcessor来达到ResultSet转换为Map对象的目的。以下不再说明

?? 4)BeanHandler<T> :将ResultSet中的第一行转换为一个指定的Bean对象返回

?

    /** 
     * 创建一个BeanHandler的新实例
     * @param type 返回对象的Class实例   
     */
    public BeanHandler(Class<T> type) {
        this(type, ArrayHandler.ROW_PR