首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Apache DbUtils 核心 ResultSetHandler 實戰速查:七大處理器完整用法

     編輯:Java 綜合教學

核心類:QueryRunner

線程安全,核心方法:

  • query(sql, ResultSetHandler<T> rsh, params...) → 查詢
  • update(sql, params...) → 增刪改(返回影響行數)

七大常用 ResultSetHandler 實戰

Handler返回類型適用場景關鍵行為
ArrayHandlerObject[]單行、無實體類映射僅取第一行,列順序對應數組下標
ArrayListHandlerList<Object[]>多行、無實體類映射每行一個數組,裝入 List
BeanHandler<T>T單行 → JavaBean列名/別名與屬性名需一致(大小寫不敏感)
BeanListHandler<T>List<T>多行 → JavaBean 列表最常用,自動逐行映射
ScalarHandler<T>T聚合查詢、單值三種構造器:
• 無參 → 第 1 行第 1 列
• int colIdx → 第 1 行第 N 列(1-based)
• String colName → 第 1 行指定列名
ColumnListHandler<T>List<T>單列多行 → List構造器同 ScalarHandler,提取指定列所有值
MapHandlerMap<String,Object>單行 → MapKey=列名,Value=列值
MapListHandlerList<Map<String,Object>>多行 → Map 列表每行一個 Map

代碼範例(假設已有 DataSource ds)

QueryRunner qr = new QueryRunner(ds);

// 1. BeanListHandler - 最常用
List<User> users = qr.query("SELECT id, name, email FROM sys_user WHERE status=1",
                            new BeanListHandler<>(User.class));

// 2. ScalarHandler - 聚合查詢
Long total = qr.query("SELECT COUNT(1) FROM sys_user",
                      new ScalarHandler<Long>());

// 3. ColumnListHandler - 只拿某一列
List<String> emails = qr.query("SELECT email FROM sys_user",
                               new ColumnListHandler<String>("email"));

// 4. MapListHandler - 無實體類、動態列
List<Map<String, Object>> rows = qr.query("SELECT * FROM sys_user LIMIT 10",
                                          new MapListHandler());

// 5. 帶參數查詢(? 佔位符,順序綁定)
User u = qr.query("SELECT * FROM sys_user WHERE id=? AND status=?",
                  new BeanHandler<>(User.class), 1001, 1);

進階技巧

自定義 Handler 處理複雜映射

// 例:將多行聚合為 Map<Long, User>,Key 為 id
ResultSetHandler<Map<Long, User>> mapHandler = rs -> {
    Map<Long, User> map = new LinkedHashMap<>();
    while (rs.next()) {
        User user = new User();
        user.setId(rs.getLong("id"));
        user.setName(rs.getString("name"));
        map.put(user.getId(), user);
    }
    return map;
};

Map<Long, User> userMap = qr.query("SELECT id, name FROM sys_user", mapHandler);

連接管理最佳實踐

  • 簡單場景:直接用 QueryRunner(ds),內部自動獲取/釋放連接。
  • 事務場景:手動獲取 Connection conn = ds.getConnection(),關閉自動提交,傳入 qr.query(conn, sql, handler, params),最後 conn.commit() / rollback() 並 close()。

常見坑點避雷

坑點後果解決
列名與屬性名不一致(如 user_name vs userName)屬性為 nullSQL 用別名 user_name AS userName,或配置 BasicRowProcessor + GenerousBeanProcessor 支援下劃線轉駝峰
ScalarHandler 無參構造器用於多行結果只取第一行,其餘丟棄確認 SQL 僅返回單行(聚合/主鍵查詢)
忘記關閉 Connection(事務模式)連接洩漏、池耗盡用 try-with-resources 或 DbUtils.closeQuietly(conn)
大結果集直接 BeanListHandlerOOM改用 ResultSetIteratorHandler 流式處理,或分頁查詢

總結

DbUtils 以 「一個 QueryRunner + N 種 ResultSetHandler」 覆蓋 95% 查詢場景。牢記 BeanListHandler(列表)、ScalarHandler(聚合)、MapListHandler(動態列)三大主力,其餘按需選擇。生產環境務必配合連接池(Druid/HikariCP)並注意事務邊界。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved