JDBC连接数据库第三步:利用开源框架Dbutils查询数据库原理及实现方案

 commons-dbutils-1.9.3.jar 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低, 并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。

0、Dbutils的query()的实现原理:

1、万变不离其宗,查询方法只不过是封装了结果集ResultSet转换为map或list的过程。

2、具体实现方法:

    (1)以BeanListHandler为例,我们期望“将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里”。代码如下:

 Connection connection = JdbcUtils.getConnection();
 List<User> userList = new ArrayList<>();
 QueryRunner runner = new QueryRunner();
 ResultSetHandler<List<User>> rsh = new BeanListHandler<User>(User.class);
 userList = runner.query(connection,sql,rsh);

     在上一篇博文说道,使用Statement或PreparedStatement执行查询,得到结果集ResultSet,然后对结果集遍历,再进行封装处理:

    public static <T> List<T> statementExecuteQuery(Class<T> clazz, final String sql){
        T entity = null;
        Statement statement = null;
        ResultSet resultSet = null;
        List<T> queryResult = new ArrayList<>();
        Connection connection= getConnection();
        if (null == connection){
            //log.error("Connection is null.");
            return null;
        }
        try {
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sql);//过程一:得到结果集
            final List<Map<String, Object>> data = converResultSetToList(resultSet);//过程二:将结果集toList
            for (Map<String, Object> map : data){//过程三:将结果集中的每一行数据都封装到一个对应的JavaBean实例中
                entity = clazz.newInstance();
                for (Map.Entry<String, Object> entry : map.entrySet()){
                    String columnName = entry.getKey();
                    Object columnValue = entry.getValue();
                    BeanUtils.setProperty(entity,columnName,columnValue);
                }
                queryResult.add(entity);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeResource(connection,null,null,resultSet);
        }
        return queryResult;
    }
    private static List<Map<String, Object>> converResultSetToList(ResultSet resultSet) throws SQLException {
        if (null == resultSet){
            return null;
        }
        List<Map<String, Object>> data = new ArrayList<>();
        ResultSetMetaData rsmd = resultSet.getMetaData();
        while (resultSet.next()){
            Map<String, Object> rowData = new HashMap<String, Object>();
            for(int i = 0,columnCount = rsmd.getColumnCount();i < columnCount; i++){
                rowData.put(rsmd.getColumnName(i + 1),resultSet.getObject(i + 1));
            }
            data.add(rowData);
        }
        return data;
    }

问:Dbutils是怎么做到封装的呢? 先看看查询实现代码:

List<T> entityList = new ArrayList<>();
Connection connection = JdbcUtils.getConnection();
QueryRunner runner = new QueryRunner();
ResultSetHandler<List<User>> rsh = new BeanListHandler<User>(User.class);
entityList = (List<T>)runner.query(connection,sql,rsh);

其实很简单,就是把上面三个过程做了封装而已,封装到 runner.query(connection,sql,rsh) 方法中。

仔细一点就是,queryRunner.query(con,sql,rsh)方法有三个参数,第一个是数据库连接对象,第二个是执行数据库查询的sql语句,第三个很重主要了,就是结果集处理ResultSetHandler的实现类。也就是你要将查询出来的一什么形式返回,是返回一个数组,还是JavaBean实例,还是Map结果,还是一个具体的结果ScalarHandler。

ResultSetHandler接口,有一个 handler 方法,queryRunner.query(con,sql,rsh) 方法将查询出来的结果集交给handler 方法来进行处理,按照 rsh 具体实现类的类型来封装处理结果集。

看看源代码:

ResultSetHandler接口:

public interface ResultSetHandler<T> {
    T handle(ResultSet var1) throws SQLException;
}

  queryRunner.query(con,sql,rsh)方法:

public <T> T query(Connection conn, String sql, ResultSetHandler
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值