转自:http://www.cnblogs.com/ysw-go/

使用DBUtils提供的功能需要使用commons-dbutils-1.6.jar这个JAR包,在Apache官网可以下载到

使用DBUtils进行更新操

测试QueryRunner类的update方法 ,该方法可用于insert,update,delete操作
具体代码实现

 1     @Test
 2     public void testQuertRunnerUpdate() {
 3         // 1.创建QueryRunner的实现类
 4         String sql = "delete from customers" + " where id in (?,?)";
 5         Connection connection = null;
 6         try {
 7             connection = JDBCTools.getConnection();
 8             queryRunner.update(connection, sql, 3, 4);
 9
10         } catch (Exception e) {
11             e.printStackTrace();
12         } finally {
13             JDBCTools.release(null, null, connection);
14         }
15     }

我们可以查看一下update方法的源码,可以看到是调用的是重载形式的update:

conn:数据库连接

sql:SQL语句

params:填充占位符的参数

1  public int update(Connection conn, String sql, Object... params) throws SQLException {
2         return update(conn, false, sql, params);
3     }

看具体实现代码:

 1     private int update(Connection conn, boolean closeConn, String sql, Object... params) throws SQLException {
 2         if (conn == null) {
 3             throw new SQLException("Null connection");
 4         }
 5
 6         if (sql == null) {
 7             if (closeConn) {
 8                 close(conn);
 9             }
10             throw new SQLException("Null SQL statement");
11         }
12         //封装使用的是PreparedStatement
13         PreparedStatement stmt = null;
14         int rows = 0;
15
16         try {
17             stmt = this.prepareStatement(conn, sql);
           //填充占位符的操作
18             this.fillStatement(stmt, params);
           //执行更新操作
19             rows = stmt.executeUpdate();
20
21         } catch (SQLException e) {
22             this.rethrow(e, sql, params);
23
24         } finally {
25             close(stmt);
26             if (closeConn) {
27                 close(conn);
28             }
29         }
30
31         return rows;
32     }

可以看到QueryRunner中封装的都是我们所熟悉的基本操作,测试我们的testQuertRunnerUpdate方法,可以发现对应id为3,4的记录已经被删除

测试QueryRunner的查询方法query

 1 // 因为是线程安全的,所以queryRunner可以放到这个位置
 2     QueryRunner queryRunner = new QueryRunner();
 3
 4     class MyResultSetHandler implements ResultSetHandler {
 5
 6         @Override
 7         public Object handle(ResultSet resultSet) throws SQLException {
 8             List<Customer> customers = new ArrayList<Customer>();
 9             while (resultSet.next()) {
10                 int id = resultSet.getInt(1);
11                 String name = resultSet.getString(2);
12                 String email = resultSet.getString(3);
13                 Date birth = resultSet.getDate(4);
14                 Customer customer = new Customer(id, name, email, birth);
15                 customers.add(customer);
16             }
17             return customers;
18         }
19
20     }
21
22     @Test
23     public void testQuery() {
24         QueryRunner queryRunner = new QueryRunner();
25         Connection connection = null;
26         try {
27             connection = JDBCTools.getConnection();
28             String sql = "select id,name,email,birth" + " from customers";
29             Object obj = queryRunner.query(connection, sql,
30                     new MyResultSetHandler());
31             System.out.println(obj);
32         } catch (Exception e) {
33             e.printStackTrace();
34         } finally {
35             JDBCTools.release(null, null, connection);
36         }
37     }

运行方法可以看到我们要查询的结果:

[Customer [id=1, name=ATGUIGU, email=simale@163.com, birth=2016-05-08], Customer [id=2, name=ABCDE, email=abcd@guigu.com, birth=2016-05-08], Customer [id=5, name=dsv, email=474405914@qq.com, birth=2016-05-10]]

我们查看一下query方法的源码

 1 private <T> T query(Connection conn, boolean closeConn, String sql, ResultSetHandler<T> rsh, Object... params)
 2             throws SQLException {
 3         if (conn == null) {
 4             throw new SQLException("Null connection");
 5         }
 6
 7         if (sql == null) {
 8             if (closeConn) {
 9                 close(conn);
10             }
11             throw new SQLException("Null SQL statement");
12         }
13
14         if (rsh == null) {
15             if (closeConn) {
16                 close(conn);
17             }
18             throw new SQLException("Null ResultSetHandler");
19         }
20
21         PreparedStatement stmt = null;
22         ResultSet rs = null;
23         T result = null;
24
25         try {
26             stmt = this.prepareStatement(conn, sql);
27             this.fillStatement(stmt, params);
28             rs = this.wrap(stmt.executeQuery());
29             result = rsh.handle(rs);
30
31         } catch (SQLException e) {
32             this.rethrow(e, sql, params);
33
34         } finally {
35             try {
36                 close(rs);
37             } finally {
38                 close(stmt);
39                 if (closeConn) {
40                     close(conn);
41                 }
42             }
43         }
44
45         return result;
46     }

其中最关键的是这四个语句:

            stmt = this.prepareStatement(conn, sql);
            this.fillStatement(stmt, params);
            rs = this.wrap(stmt.executeQuery());
            result = rsh.handle(rs);
测试DBUtils工具类 QueryRunner:
 * query(Connection conn,String sql,ResultSetHandler rsh){
 * 这三个步骤就是为了得到结果集
 * stmt = this.prepareStatement(conn, sql);
 * this.fillStatement(stmt, params);
 * rs = this.wrap(stmt.executeQuery());
 * 调用传入的ResultSetHandler对象的handle方法,并且把前面得到的ResultSet对象作为参数传入
 * result =rsh.handle(rs);
 * 把result作为结果返回
 * return result
 * }

测试BeanHandler的用法
BeanHandler:把结果集的第一条记录转为创建BeanHandler 对象时传入的Class参数对应的对象。

具体测试代码:

 1 public void testBeanHandler() {
 2         Connection connection = null;
 3         try {
 4             connection = JDBCTools.getConnection();
 5             String sql = "select id,name,email,birth"
 6                     + " from customers where id=?";
 7             Customer customer = queryRunner.query(connection, sql,
 8                     new BeanHandler(Customer.class), 5);
 9             System.out.println(customer);
10         } catch (Exception e) {
11             e.printStackTrace();
12         } finally {
13             JDBCTools.release(null, null, connection);
14         }
15     }

查看源码可以看到query函数中用到的handler函数实现的功能是这样的

1   @Override
2     public T handle(ResultSet rs) throws SQLException {
3         return rs.next() ? this.convert.toBean(rs, this.type) : null;
4     }

实现的功能是把结果集的第一条记录转为创建BeanHandler 对象时传入的Class参数对应的对象。

其中的toBean方法的实现方式:(多看源码吧,有点乱了)

    public <T> T toBean(ResultSet rs, Class<T> type) throws SQLException {

        PropertyDescriptor[] props = this.propertyDescriptors(type);

        ResultSetMetaData rsmd = rs.getMetaData();
        int[] columnToProperty = this.mapColumnsToProperties(rsmd, props);

        return this.createBean(rs, type, props, columnToProperty);
    }

测试BeanListHandler的用法
和前面那个差不多,只不过将查询的结果放到了一个List容器中了

 1     @Test
 2     public void testBeanListHandler() {
 3         Connection connection = null;
 4         try {
 5             connection = JDBCTools.getConnection();
 6             String sql = "select id,name,email,birth" + " from customers";
 7             List<Customer> customers = queryRunner.query(connection, sql,
 8                     new BeanListHandler(Customer.class));
 9             System.out.println(customers);
10         } catch (Exception e) {
11             e.printStackTrace();
12         } finally {
13             JDBCTools.release(null, null, connection);
14         }
15     }

运行结果:

[Customer [id=1, name=ATGUIGU, email=simale@163.com, birth=2016-05-08], Customer [id=2, name=ABCDE, email=abcd@guigu.com, birth=2016-05-08], Customer [id=5, name=dsv, email=474405914@qq.com, birth=2016-05-10]]

测试MapHandler的用法

MapHandler:返回SQL对应的第一条记录对应的Map对象 键:SQL查询的列名(不是列别名) 值:列的值

 1 @Test
 2     public void testMapHandler() {
 3         Connection connection = null;
 4         try {
 5             connection = JDBCTools.getConnection();
 6             String sql = "select id,name,email,birth" + " from customers";
 7             Map<String, Object> result = queryRunner.query(connection, sql,
 8                     new MapHandler());
 9             System.out.println(result);
10         } catch (Exception e) {
11             e.printStackTrace();
12         } finally {
13             JDBCTools.release(null, null, connection);
14         }
15     }

运行结果:

{id=1, name=ATGUIGU, email=simale@163.com, birth=2016-05-08}

测试MapListHandler的用法

MapListHandler:将结果集转为一个Map的List, Map对应查询的一条记录的Map对象

键:SQL查询的列名(不是列别名)
值:列的值 而MapListHandler:返回的多条记录对应的Map集合

 1 @Test
 2     public void testMapListHandler() {
 3         Connection connection = null;
 4         try {
 5             connection = JDBCTools.getConnection();
 6             String sql = "select id,name,email,birth" + " from customers";
 7             List<Map<String, Object>> result = queryRunner.query(connection,
 8                     sql, new MapListHandler());
 9             System.out.println(result);
10         } catch (Exception e) {
11             e.printStackTrace();
12         } finally {
13             JDBCTools.release(null, null, connection);
14         }
15     }

运行结果:

[{id=1, name=ATGUIGU, email=simale@163.com, birth=2016-05-08}, {id=2, name=ABCDE, email=abcd@guigu.com, birth=2016-05-08}, {id=5, name=dsv, email=474405914@qq.com, birth=2016-05-10}]

测试ScalarHandler的用法

ScalarHandle:把结果集转为一个数值(可以是任意基本数据类型和字符串,Date等)返回

 1 @Test
 2     public void testScalarHandler() {
 3         Connection connection = null;
 4         try {
 5             connection = JDBCTools.getConnection();
 6             String sql = "select count(id) from customers";
 7             Object result = queryRunner.query(connection, sql,
 8                     new ScalarHandler());
 9             System.out.println(result);
10         } catch (Exception e) {
11             e.printStackTrace();
12         } finally {
13             JDBCTools.release(null, null, connection);
14         }
15     }

运行结果:3

至此为止我们学习了JDBC中常用的一些知识点,下面我们就使用DBUtils编写通用的DAO(DAO其实就是封装了操作数据库数据的一些方法的接口)

使用DButils编写通用的DAO

第一步:先写一个访问数据的DAO接口

 1 package com.atguigu.jdbc;
 2
 3 import java.sql.Connection;
 4 import java.util.List;
 5
 6 /**
 7  * 访问数据的DAO接口
 8  * 里面定义好访问数据表的各种方法
 9  * @author Administrator
10  * @param T:DAO处理的实体类的类型
11  */
12 public interface DAO {
13     /**
14      * 批量处理的方法
15      * @param connection
16      * @param sql
17      * @param args:填充占位符的Object[]类型的可变参数
18      */
19     void batch(Connection connection,
20     String sql,Object[] ...args);
21     /**
22      * 返回一个具体的一个值,例如总人数,平均工资
23      * 某一个认得email
24      * @param connection
25      * @param sql
26      * @param args
27      * @return
28      */
29     <E> E getForValue(Connection connection,
30     String sql,    Object ...args);
31
32     /**
33      * 返回T的一个集合
34      * @param <T>
35      * @param connection
36      * @param sql
37      * @param args
38      * @return
39      */
40     <T> List<T> getForList(Connection connection,
41     String sql,Object ...args);
42     /**
43      * 返回一个T的对象
44      * @param <T>
45      * @param connection
46      * @param sql
47      * @param args
48      * @return
49      * @throws Exception
50      */
51     <T> T get(Connection connection,String sql,Object ...args) throws Exception;
52     /**
53      *
54      * @param connection:数据库连接
55      * @param sql:SQL语句
56      * @param args:填充占位符的可变参数
57      */
58     void update(Connection connection,String sql,Object ...args);
59 }

第二步:定义实现该接口的实例类JdbcDAOImpl

 1 package com.atguigu.jdbc;
 2
 3 import java.sql.Connection;
 4 import java.util.List;
 5
 6 import org.apache.commons.dbutils.QueryRunner;
 7 import org.apache.commons.dbutils.handlers.BeanHandler;
 8
 9 /**
10  * 使用QueryRunner提供其具体的实现
11  * @author Administrator
12  *
13  * @param <T>:子类需传入的泛型类型
14  */
15 public class JdbcDAOImpl<T> implements DAO {
16     private QueryRunner queryRunner=null;
17     private Class<T> type;
18     public  JdbcDAOImpl() {
19         queryRunner=new QueryRunner();
20         type= (Class<T>) ReflectionUtils.getGenericSuperClass(getClass(),0);
21     }
22     @Override
23     public void batch(Connection connection, String sql, Object[]... args) {
24     }
25
26     @Override
27     public <E> E getForValue(Connection connection, String sql, Object... args) {
28
29         return null;
30     }
31
32     @Override
33     public  List<T> getForList(Connection connection, String sql,
34             Object... args) {
35
36         return null;
37     }
38
39     @Override
40     public  T get(Connection connection, String sql, Object... args) throws Exception {
41
42         return  queryRunner.query(connection, sql,
43         new BeanHandler<>(type),args);
44     }
45
46     @Override
47     public void update(Connection connection, String sql, Object... args) {
48     }
49
50
51 }

第三步:定义一个具体操作的类继承自JdbcDAOImpl

1 package com.atguigu.jdbc;
2
3 public class CustomerDAO extends JdbcDAOImpl<Customer>{
4
5 }

第四步:我们测试一下我们已经实现的get方法,其他的方法实现过程类似

 1 package com.atguigu.jdbc;
 2
 3 import static org.junit.Assert.*;
 4
 5 import java.sql.Connection;
 6
 7 import org.junit.Test;
 8
 9 public class CustomerDaoTest {
10     CustomerDAO customerDAO=new CustomerDAO();
11
12     @Test
13     public void testBatch() {
14         fail("Not yet implemented");
15     }
16
17     @Test
18     public void testGetForValue() {
19         fail("Not yet implemented");
20     }
21
22     @Test
23     public void testGetForList() {
24         fail("Not yet implemented");
25     }
26
27     @Test
28     public void testGet() {
29         Connection connection=null;
30         try {
31             connection=JDBCTools.getConnection();
32             String sql = "select id,name,email,birth"
33                     + " from customers where id=?";
34             Customer customer=customerDAO.get(connection, sql, 5);
35             System.out.println(customer);
36         } catch (Exception e) {
37             e.printStackTrace();
38         }finally{
39             JDBCTools.release(null, null, connection);
40         }
41     }
42
43     @Test
44     public void testUpdate() {
45         fail("Not yet implemented");
46     }
47
48 }

运行一下:

Customer [id=5, name=dsv, email=474405914@qq.com, birth=2016-05-10]

可以通过我们的get方法得到我们想要的数据信息

【转】JDBC学习笔记(9)——DBUtils的使用的更多相关文章

  1. JDBC学习笔记(9)——DBUtils的使用

    使用DBUtils提供的功能需要使用commons-dbutils-1.6.jar这个JAR包,在Apache官网可以下载到 使用DBUtils进行更新操 测试QueryRunner类的update方 ...

  2. JDBC 学习笔记(十一)—— JDBC 的事务支持

    1. 事务 在关系型数据库中,有一个很重要的概念,叫做事务(Transaction).它具有 ACID 四个特性: A(Atomicity):原子性,一个事务是一个不可分割的工作单位,事务中包括的诸操 ...

  3. JDBC 学习笔记(十)—— 使用 JDBC 搭建一个简易的 ORM 框架

    1. 数据映射 当我们获取到 ResultSet 之后,显然这个不是我们想要的数据结构. 数据库中的每一个表,在 Java 代码中,一定会有一个类与之对应,例如: package com.gerrar ...

  4. JDBC 学习笔记(六)—— PreparedStatement

    1. 引入 PreparedStatement PreparedStatement 通过 Connection.createPreparedStatement(String sql) 方法创建,主要用 ...

  5. JDBC学习笔记二

    JDBC学习笔记二 4.execute()方法执行SQL语句 execute几乎可以执行任何SQL语句,当execute执行过SQL语句之后会返回一个布尔类型的值,代表是否返回了ResultSet对象 ...

  6. JDBC学习笔记一

    JDBC学习笔记一 JDBC全称 Java Database Connectivity,即数据库连接,它是一种可以执行SQL语句的Java API. ODBC全称 Open Database Conn ...

  7. JDBC学习笔记(2)——Statement和ResultSet

    Statement执行更新操作 Statement:Statement 是 Java 执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句.Statement ...

  8. JDBC学习笔记(1)——JDBC概述

    JDBC JDBC API是一个Java API,可以访问任何类型表列数据,特别是存储在关系数据库中的数据.JDBC代表Java数据库连接. JDBC库中所包含的API任务通常与数据库使用: 连接到数 ...

  9. 【转】JDBC学习笔记(2)——Statement和ResultSet

    转自:http://www.cnblogs.com/ysw-go/ Statement执行更新操作 Statement:Statement 是 Java 执行数据库操作的一个重要方法,用于在已经建立数 ...

随机推荐

  1. 百度地图API新手入门

    最近,共享单车着实火了一把,市场竞争也是异常的激烈,百花争艳,百家争鸣,群雄逐鹿,最后鹿死谁手,现在还不得而知,不过可以肯定的是细节决定成败,更重要的还在于用户的体验. 用过的同学们都会知道,打开共享 ...

  2. ajax 实现三级联动

    ajax 实现三级联动,相当于写了一个小插件,用的时候直接拿过来用就可以了,这里我用了数据库中的chinastates表, 数据库内容很多,三级联动里的地区名称都在里面,采用的是代号副代号的方式 比如 ...

  3. JSON对象操作

    ---string 转jsonObject JSONObject j = JSONObject.fromObject(str); JSONObject j = JSONObject.fromObjec ...

  4. Linux系统常用命令总结

    1. 最关键的命令 manecho 2. 目录文件操作命令 ls: 查看目录下的文件信息或文件信息dir:pwd: 打印当前路径cd:改变路径mkdir:创建路径rmdir:删除路径cp:拷贝文件或目 ...

  5. 通过spring 中的@Scheduled来执行定时任务

    以前开发定时任务的功能的时候,是框架里面写好的quartz配置方式,由于功力尚浅,感觉定时跑披定时任务什么的云里雾里,很高大上,每次都不知道怎么修改配置,后来几次接触定时任务发现,还是比较好掌握的,特 ...

  6. WF学习思维导图

    原文 来自我的有道笔记-老文重发系列 如果配置加载核心服务,那么需要将持久化服务和跟踪服务放在一个数据库中!   1.用工作流的优点 a.提供将复杂任务分解的途径,通过将每个操作分解到活动中更便于业务 ...

  7. CentOS 安装mysql-5.7.10(glibc版)

    注:所有shell命令都以root用户执行. 一.下载 shell> cd /home/user/Downloads shell> wget http://mirrors.sohu.com ...

  8. Ext JS 6学习文档–第1章–ExtJS入门指南

    Ext JS 入门指南 前言 本来我是打算自己写一个系列的 ExtJS 6 学习笔记的,因为 ExtJS 6 目前的中文学习资料还很少.google 搜索资料时找到了一本国外牛人写的关于 ExtJS ...

  9. 利用python的爬虫技术爬去糗事百科的段子

    初次学习爬虫技术,在知乎上看了如何爬去糗事百科的段子,于是打算自己也做一个. 实现目标:1,爬取到糗事百科的段子 2,实现每次爬去一个段子,每按一次回车爬取到下一页 技术实现:基于python的实现, ...

  10. javascript面向对象(一)

    javascript是弱类型,直译式的面相对象编程语言. 在之前我们说过 var a = 123: 在这里a是整数 但是我们可以给a重新复制为 a="你好"; 在这个过程中变量a ...