黑马程序员技术交流社区

标题: DbUtils中QueryRunner源码解析 [打印本页]

作者: 大山哥哥    时间: 2017-9-26 19:37
标题: DbUtils中QueryRunner源码解析
本帖最后由 大山哥哥 于 2017-9-26 19:41 编辑

QueryRunner.java
通过dbutils进行查询操作的得时候调用QueryRunner的query方法
[Java] 纯文本查看 复制代码
    public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
        return this.<T>query(conn, false, sql, rsh, params);
    }
调用重载方法
[Java] 纯文本查看 复制代码

    private <T> T query(Connection conn, boolean closeConn, String sql, ResultSetHandler<T> rsh, Object... params)
            throws SQLException {
                //判断数据库连接
        if (conn == null) {
            throw new SQLException("Null connection");
        }
                //判断sql语句
        if (sql == null) {
            if (closeConn) {
                close(conn);
            }
            throw new SQLException("Null SQL statement");
        }
                //判断处理的结果集实现类
        if (rsh == null) {
            if (closeConn) {
                close(conn);
            }
            throw new SQLException("Null ResultSetHandler");
        }
               
        PreparedStatement stmt = null;
        ResultSet rs = null;
        T result = null;

        try {
                        //sql预编译执行平台
            stmt = this.prepareStatement(conn, sql);
            this.fillStatement(stmt, params);
                        //执行查询操作
            rs = this.wrap(stmt.executeQuery());
                        //对结果集进行下一步处理
                        //--------------------------重点---------------------------------
            result = rsh.handle(rs);
                        //--------------------------重点---------------------------------
        } catch (SQLException e) {
           ...
        } finally {
           ...
        }

        return result;
    }
通过标记代码发现,对结果的处理是由ResultSetHandler的子类实现的
ResultSetHandler实现类,ArrayHandler和ArrayListHandler源码分析
因为整体差不多,所以以这2个点击进行分析
Interface ResultSetHandler 通过api文档看出该类为接口,所以实现类都需要实现其handle方法
所以入口就在具体实现类的handle方法上
ArrayHandler.java
[Java] 纯文本查看 复制代码
    public Object[] handle(ResultSet rs) throws SQLException {
                //如果查询结果集存在数据调用RowProcessor对象的toArray()方法
        return rs.next() ? this.convert.toArray(rs) : EMPTY_ARRAY;
    }
RowProcessor.java
本身为接口,所以要找具体实现类,实现类是BasicRowProcessor.java
[Java] 纯文本查看 复制代码
    public Object[] toArray(ResultSet rs) throws SQLException {
        ResultSetMetaData meta = rs.getMetaData();
                //获取到列的数量
        int cols = meta.getColumnCount();
                //创建一个长度为列的数量的Object[]数组
        Object[] result = new Object[cols];
       
        for (int i = 0; i < cols; i++) {
                        //把每列对应的数据塞到数组对应的位置
            result = rs.getObject(i + 1);
        }
                //将改数组返回到调用处 ArrayHandler的handle方法
        return result;
    }
ArrayListHandler.java
先看继承结构
class ArrayListHandler extends AbstractListHandler<Object[]>
abstract class AbstractListHandler implements ResultSetHandler<List>
首先,判断出ArrayListHandler的父类也是实现了ResultSetHandler接口
AbstractListHandler.java
[Java] 纯文本查看 复制代码
    public List<T> handle(ResultSet rs) throws SQLException {
                //创建一个arraylist
        List<T> rows = new ArrayList<T>();
        while (rs.next()) {
                        //循环取出所有结果然后添加到rows集合中
            rows.add(this.handleRow(rs));
        }
        return rows;
    }

    protected abstract T handleRow(ResultSet rs) throws SQLException;
this.handleRow(rs)这个方法表示是带哦用本类对象的handleRow(rs)方法,而AbstractListHandler为抽象类,所以无法直接创建对象,所以具体对象为ArrayListHandler.java.所以定位到ArrayListHandler的handleRow方法
ArrayListHandler.java
[Java] 纯文本查看 复制代码
    protected Object[] handleRow(ResultSet rs) throws SQLException {
        return this.convert.toArray(rs);
    }
调用RowProcessor对象的toArray()方法
RowProcessor.java
本身为接口,所以要找具体实现类,实现类是BasicRowProcessor.java

[Java] 纯文本查看 复制代码
    public Object[] toArray(ResultSet rs) throws SQLException {
        ResultSetMetaData meta = rs.getMetaData();
                //获取到列的数量
        int cols = meta.getColumnCount();
                //创建一个长度为列的数量的Object[]数组
        Object[] result = new Object[cols];
       
        for (int i = 0; i < cols; i++) {
                        //把每列对应的数据塞到数组对应的位置
            result = rs.getObject(i + 1);
        }
                //将改数组返回到调用处 AbstractListHandler的handle方法
        return result;
    }


作者: Oliverwqcwrw    时间: 2017-9-26 20:54
6666666666666666
作者: 播妞    时间: 2017-9-27 10:24
厉害了,谢谢老师分享~




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2