DBUtils入门

417 阅读3分钟

DBUtils

1. 简介

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

使用 DBUtils 需要导入 commons-dbutils-1.7.jar。DBUtils 有三个核心的组件:

  1. QueryRunner:该类提供了 DML 和 DQL 的API。
  2. ResultSetHandler:该接口定义如何封装结果集。
  3. DbUtils:一个简单的工具类,简化了关闭资源和事务处理。

2. QueryRunner

2.1 构造方法

QueryRunner(); // 需要指定连接
QueryRunner(DataSource ds);   //从数据源中获取连接

2.2 常用 API

<T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params);
<T> T query(Connection conn, String sql, ResultSetHandler<T> rsh);
<T> T query(String sql, ResultSetHandler<T> rsh, Object... params);
<T> T query(String sql, ResultSetHandler<T> rsh);

int update(Connection conn, String sql, Object... params);
int update(Connection conn, String sql);
int update(String sql, Object... params);
int update(String sql);

int[] batch(Connection conn, String sql, Object[][] params)
int[] batch(String sql, Object[][] params)

2.3 CRUD

    @Test
    public void testInsert() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "insert into t_user(username, password, balance) values (?, ?, ?)";
        Object[] params = {"Thomas_He", "123456", "1000"};
        int rows = queryRunner.update(sql, params);
        Assert.assertEquals(1, rows);
    }

    @Test
    public void testUpdate() throws SQLException {
        QueryRunner queryRunner = new QueryRunner();
        String sql = "update t_user set balance = balance - 100 where id = ?";
        Object param = 1;
        Connection conn = getConnection();
        int rows = queryRunner.update(conn, sql, param);
        Assert.assertEquals(1, rows);
    }

    @Test
    public void testDelete() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "delete from t_user where id = ?";
        Object param = 3;
        int rows = queryRunner.update(sql, 3);
        Assert.assertEquals(1, rows);
    }

	@Test
    public void testQuery() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "select * from t_user where id = ?";
        User user = queryRunner.query(sql, new BeanHandler<>(User.class), 1);
        System.out.println(user);
        Assert.assertEquals(700, user.getBalance());
    }

    @Test
    public void testBatch() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "insert into t_user (username, password, balance) values (?,?,?)";
        Object[][] params = new Object[1000][3];
        for (int i = 0; i < 1000; i++) {
            params[i] = new Object[]{"user" + i, "pwd" + i, i};
        }
        int[] rowsArr = queryRunner.batch(sql, params);
    }

3. ResultSetHandler

该接口用于处理 ResultSet,将查询返回的 ResultSet 按要求转换为另一种形式。该接口的定义如下:

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

3.1 该接口的实现类

  • ArrayHandler:把结果集中的第一行数据转成对象数组。
  • ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
  • BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
  • BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
  • ColumnListHandler:将结果集中某一列的数据存放到List中。
  • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
  • MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
  • MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List。

3.2 演示

    @Test
    public void testArrayHandler() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "select * from t_user";
        Object[] arr = queryRunner.query(sql, new ArrayHandler());
        System.out.println(Arrays.toString(arr));
    }

    @Test
    public void testArrayListHandler() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "select * from t_user";
        List<Object[]> list = queryRunner.query(sql, new ArrayListHandler());
        for (Object[] arr : list) {
            System.out.println(Arrays.toString(arr));
        }
    }

    @Test
    public void testBeanHandler() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "select * from t_user";
        User user = queryRunner.query(sql, new BeanHandler<>(User.class));
        System.out.println(user);
    }

    @Test
    public void testBeanListHandler() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "select * from t_user";
        List<User> users = queryRunner.query(sql, new BeanListHandler<>(User.class));
        for (User user : users) {
            System.out.println(user);
        }
    }

	@Test
    public void testColumnListHandler() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "select username from t_user";
        List<String> names = queryRunner.query(sql, new ColumnListHandler<String>());
        for(String name : names) {
            System.out.println(name);
        }
    }

	@Test
    public void testKeyedHandler() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(getDataSource());
        String sql = "select * from t_user";
        Map<Integer, Map<String, Object>> map = queryRunner.query(sql, new 			 	KeyedHandler<Integer>("id"));
        System.out.println(map);
    }
	
	

使用 BeanHandler 和 BeanListHandler 需要注意以下几点:

  1. 对应的 JavaBean 必须提供无参构造方法。
  2. JavaBean 的属性名应该和返回结果的字段名相同。
  3. JavaBean 中必须提供公共的 Setter 方法。

4. DbUtils

提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的。

主要有以下API:

void close(Connection conn); //可以避免空指针异常
void close(ResultSet rs);
void close(Statement stmt);

void closeQuietly(Connection conn); //不需要判空, 处理异常
void closeQuietly(ResultSet rs); 
void closeQuietly(Statement stmt);
void closeQuietly(Connection conn, Statement stmt, ResultSet rs);

void commitAndClose(Connection conn); // 提交事务并且关闭连接
void commitAndCloseQuietly(Connection conn);

boolean	loadDriver(String driverClassName)