09、Apache-DBUtils实现CRUD操作
9.1、Apache-DBUtils简介
commons-dbutils
是Apache
组织提供的一个开源JDBC
工具类库,它是对JDBC
的简单封装,学习成本极低,并且使用dbutils
能极大简化jdbc
编码的工作量,同时也不会影响程序的性能。API
介绍:org.apache.commons.dbutils.QueryRunner
org.apache.commons.dbutils.ResultSetHandler
- 工具类:
org.apache.commons.dbutils.DbUtils
9.2、主要API的使用
9.2.1、DbUtils
DbUtils
:提供如关闭连接、装载JDBC
驱动程序等常规工作的工具类,里面的所有方法都是静态的。主要方法如下:public static void close(…) throws java.sql.SQLException
:DbUtils
类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL
,如果不是的话,它们就关闭Connection
、Statement
和ResultSet
。public static void closeQuietly(…)
: 这一类方法不仅能在Connection
、Statement
和ResultSet
为NULL
情况下避免关闭,还能隐藏一些在程序中抛出的SQLException
。public static void commitAndClose(Connection conn)throws SQLException
: 用来提交连接的事务,然后关闭连接。public static void commitAndCloseQuietly(Connection conn)
: 用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL
异常。public static void rollback(Connection conn)throws SQLException
:允许conn
为null
,因为方法内部做 了判断。public static void rollbackAndClose(Connection conn)throws SQLException
rollbackAndCloseQuietly(Connection)
public static boolean loadDriver(java.lang.String driverClassName)
:这一方装载并注册JDBC
驱动程序,如果成功就返回true
。使用该方法,你不需要捕捉这个异常ClassNotFoundException
。
9.2.2、QueryRunner类
-
提供数据库操作的一系列重载的
update()
和query()
操作。 -
该类简单化了
SQL
查询,它与ResultSetHandler
组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。 -
QueryRunner
类提供了两个构造器:- 默认的构造器
- 需要一个
javax.sql.DataSource
来作参数的构造器
-
QueryRunner
类的主要方法:- 更新
public int update(Connection conn, String sql, Object... params) throws SQLException
:用来执行 一个更新(插入、更新或删除)操作。- …
- 插入
public T insert(Connection conn,String sql,ResultSetHandler rsh, Object... params) throws SQLException
:只支持INSERT
语句,其中rsh - The handler used to create the result object from the ResultSet of auto-generated keys
. 返回值:An object generated by the handler
。即自动生成的键值。- …
- 批处理
public int[] batch(Connection conn,String sql,Object[][] params)throws SQLException
:INSERT
,UPDATE
, orDELETE
语句public T insertBatch(Connection conn,String sql,ResultSetHandler rsh,Object[][] params)throws SQLException
:只支持INSERT
语句- …
- 查询
public Object query(Connection conn, String sql, ResultSetHandler rsh,Object... params) throws SQLException
:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理PreparedStatement
和ResultSet
的创建和关闭。- …
- 更新
-
测试:
-
测试添加数据
//测试添加 @Test public void testInsert() { Connection con = null; try { QueryRunner runner = new QueryRunner(); con = JDBCUtil.getConnection2(); String sql = "insert into customers(name, email,birth) values (?,?,?)"; int insertCount = runner.update(con, sql, "cxk", "cxk123@gemail.com", "1997-09-07"); System.out.println("添加了" + insertCount + "条记录!"); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, null); } }
-
测试删除数据
//测试删除 @Test public void testDelete() { Connection con = null; try { QueryRunner runner = new QueryRunner(); con = JDBCUtil.getConnection2(); String sql = "delete from customers where id = ?"; int deleteCount = runner.update(con, sql, 9); System.out.println("删除了" + deleteCount + "条记录!"); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, null); } }
-
9.2.3、ResultSetHandler接口及实现类
-
该接口用于处理
java.sql.ResultSet
,将数据按要求转换为另一种形式。 -
ResultSetHandler
接口提供了一个单独的方法:Object handle (java.sql.ResultSet.rs)
。 -
接口的主要实现类:
ArrayHandler
:把结果集中的第一行数据转成对象数组。ArrayListHandler
:把结果集中的每一行数据都转成一个数组,再存放到List
中。BeanHandler
:将结果集中的第一行数据封装到一个对应的JavaBean
实例中。BeanListHandler
:将结果集中的每一行数据都封装到一个对应的JavaBean
实例中,存放到List
里。ColumnListHandler
:将结果集中某一列的数据存放到List
中。KeyedHandler(name)
:将结果集中的每一行数据都封装到一个Map
里,再把这些map
再存到一个map
里,其key
为指定的key
。MapHandler
:将结果集中的第一行数据封装到一个Map
里,key
是列名,value
就是对应的值。MapListHandler
:将结果集中的每一行数据都封装到一个Map
里,然后再存放到List
。ScalarHandler
:查询单个值对象。
-
测试:
-
-
测试查询一条数据:
BeanHandler
/** * BeanHandler: 是 ResultSetHandler接口的实现类,用于封装表中的一条记录 */ @Test public void testQuery1() { Connection con = null; try { QueryRunner runner = new QueryRunner(); con = JDBCUtil.getConnection2(); String sql = " select id, name, email,birth from customers where id = ?"; BeanHandler<Customer> handler = new BeanHandler<>(Customer.class); Customer customer = runner.query(con, sql, handler, 13); System.out.println(customer); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, null); } }
-
测试查询多条数据:
BeanListHandler
/** * BeanListHandler: 是 ResultSetHandler接口的实现类,用于封装表中的多条记录构成的集合 */ @Test public void testQuery2() { Connection con = null; try { QueryRunner runner = new QueryRunner(); con = JDBCUtil.getConnection2(); String sql = " select id, name, email,birth from customers where id < ?"; BeanListHandler<Customer> handler = new BeanListHandler<>(Customer.class); List<Customer> list = runner.query(con, sql, handler, 13); list.forEach(System.out :: println); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, null); } }
-
测试查询一条数据:
MapHandler
/** * MapHandler: 是 ResultSetHandler接口的实现类,对应表中的一条记录 * 将字段及相应字段的值作为 map的 key和 value */ @Test public void testQuery3() { Connection con = null; try { QueryRunner runner = new QueryRunner(); con = JDBCUtil.getConnection2(); String sql = " select id, name, email,birth from customers where id = ?"; MapHandler handler = new MapHandler(); Map<String, Object> map = runner.query(con, sql, handler, 13); System.out.println(map); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, null); } }
-
测试查询多条数据:
MapListHandler
/** * MapListHandler: 是 ResultSetHandler接口的实现类,对应表中的多条记录 * 将字段及相应字段的值作为 map的 key和 value,将这些 map添加到 list */ @Test public void testQuery4() { Connection con = null; try { QueryRunner runner = new QueryRunner(); con = JDBCUtil.getConnection2(); String sql = " select id, name, email,birth from customers where id < ?"; MapListHandler handler = new MapListHandler(); List<Map<String, Object>> list = runner.query(con, sql, handler, 13); list.forEach(System.out :: println); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, null); } }
-
测试查询特殊值:
ScalarHandler
/** * ScalarHandler: 是 ResultSetHandler接口的实现类,用于查询特殊值 */ @Test public void testQuery5() { Connection con = null; try { QueryRunner runner = new QueryRunner(); con = JDBCUtil.getConnection2(); String sql = " select count(*) from customers"; ScalarHandler handler = new ScalarHandler(); Long count = (Long) runner.query(con, sql, handler); System.out.println(count); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, null); } } /** * ScalarHandler: 是 ResultSetHandler接口的实现类,用于查询特殊值 */ @Test public void testQuery6() { Connection con = null; try { QueryRunner runner = new QueryRunner(); con = JDBCUtil.getConnection2(); String sql = " select max(birth) from customers"; ScalarHandler handler = new ScalarHandler(); Date maxBirth = (Date) runner.query(con, sql, handler); System.out.println(maxBirth); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, null); } }
-
-
自定义
ResultSetHandler
的实现类/** * 自定义 ResultSetHandler的实现类 */ @Test public void testQuery7() { Connection con = null; try { QueryRunner runner = new QueryRunner(); con = JDBCUtil.getConnection2(); String sql = "select id, name, email, birth from customers where id = ?"; ResultSetHandler<Customer> handler = new ResultSetHandler<Customer>() { @Override public Customer handle(ResultSet rs) throws SQLException { if (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); String email = rs.getString("email"); Date birth = rs.getDate("birth"); Customer customer = new Customer(id, name, email, birth); return customer; } return null; } }; Customer customer = runner.query(con, sql, handler, 10); System.out.println(customer); } catch (Exception e) { e.printStackTrace(); } finally { JDBCUtil.closeResource(con, null); } }
9.3、DbUtils类关闭资源
/**
* 使用 dbutils.jar中提供的 DbUtils工具类,实现资源的关闭
* @param conn
* @param psm
* @param rs
*/
public static void closeResource1(Connection conn, PreparedStatement psm, ResultSet rs) {
/*try {
DbUtils.close(conn);
} catch (SQLException e) {
e.printStackTrace();
}
try {
DbUtils.close(psm);
} catch (SQLException e) {
e.printStackTrace();
}
try {
DbUtils.close(rs);
} catch (SQLException e) {
e.printStackTrace();
}*/
DbUtils.closeQuietly(conn);
DbUtils.closeQuietly(psm);
DbUtils.closeQuietly(rs);
}