Commons DbUtils 是對 JDBC 的輕量封裝,不改變 SQL 編寫習慣,卻能消除 90% 的樣板代碼(連接、語句、結果集、關閉、異常處理)。本文系統講解 QueryRunner 構造與執行方法、ResultSetHandler 七大內置實現、DbUtils 關閉工具類,並附帶完整 JUnit 測試代碼。
// 1. 無參構造:每次執行需傳入 Connection
QueryRunner runner = new QueryRunner();
// 2. DataSource 構造:自動獲取/歸還連接,適合無連接池管理場景
QueryRunner runner = new QueryRunner(dataSource);
| 方法簽名 | 用途 | 連接管理 |
|---|---|---|
| query(Connection, sql, params[], rsh) | 查詢,手動管理連接 | 調用者負責關閉 Connection |
| query(sql, params[], rsh) | 查詢,自動從 DataSource 獲取連接 | 內部自動關閉 Connection |
| query(Connection, sql, rsh) | 無參查詢 | 調用者負責關閉 |
| update(Connection, sql, params[]) | 增刪改,返回影響行數 | 調用者負責關閉 |
| update(Connection, sql) | 無參增刪改 | 調用者負責關閉 |
| update(sql, params[]) | 自動連接增刪改 | 內部自動關閉 |
| batch(sql, Object[][] params) | 批量執行 | 視構造方式而定 |
| 處理器 | 返回類型 | 適用場景 | 示例 |
|---|---|---|---|
| BeanHandler<T> | T | 單行 → JavaBean | new BeanHandler<>(User.class) |
| BeanListHandler<T> | List<T> | 多行 → List<JavaBean> | new BeanListHandler<>(User.class) |
| ArrayHandler | Object[] | 單行 → 對象數組 | new ArrayHandler() |
| ArrayListHandler | List<Object[]> | 多行 → List<數組> | new ArrayListHandler() |
| MapHandler | Map<String,Object> | 單行 → 鍵值對 | new MapHandler() |
| MapListHandler | List<Map<String,Object>> | 多行 → List<Map> | new MapListHandler() |
| ScalarHandler<T> | T | 單值聚合 | new ScalarHandler<Long>() |
// 安全關閉(null 安全、吞噬 SQLException)
DbUtils.close(connection);
DbUtils.close(statement);
DbUtils.close(resultSet);
DbUtils.closeQuietly(connection, statement, resultSet); // 批量靜默關閉
// 提交並關閉
DbUtils.commitAndCloseQuietly(connection);
// 載入驅動(無需捕獲 ClassNotFoundException)
boolean ok = DbUtils.loadDriver("com.mysql.jdbc.Driver");
public class DbUtilsDemo {
private QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
@Test public void testBeanHandler() throws SQLException {
User user = runner.query("SELECT * FROM user_info", new BeanHandler<>(User.class));
System.out.println("beanHandler: " + user);
}
@Test public void testBeanListHandler() throws SQLException {
List users = runner.query("SELECT * FROM user_info", new BeanListHandler<>(User.class));
users.forEach(System.out::println);
}
@Test public void testArrayHandler() throws SQLException {
Object[] arr = runner.query("SELECT * FROM user_info", new ArrayHandler());
System.out.println("ID: " + arr[0] + ", Name: " + arr[1]);
}
@Test public void testArrayListHandler() throws SQLException {
List
QueryRunner + BeanListHandler,返回領域模型。runner.update(conn, sql, params)。ResultSetHandler 自定義實現或遷移 MyBatis。DataAccessException,避免 SQLException 外洩。DbUtils 以「極簡、不侵入、零依賴」成為輕量級項目、微服務 Sidecar、遷移期過渡層的最佳選擇;複雜業務建議直接上 MyBatis/JPA,獲得完整映射、緩存、動態 SQL 能力。