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

Hibernate 分頁查詢實現原理深度解析:跨資料庫可移植方案

     編輯:Java 相關知識

應用層面 API 簡單易用

Query q = session.createQuery("from Cat as c");
q.setFirstResult(20000);  // 從第 20001 筆開始
q.setMaxResults(100);     // 取 100 筆
List l = q.list();

底層實現機制:Loader 類核心邏輯

Hibernate 根據資料庫方言採用三層降級策略:

策略一:資料庫原生 LIMIT/ROWNUM 語法(首選)

// Dialect 介面
public boolean supportsLimit() { return true; }
public String getLimitString(String sql) {
    return sql + " limit ?, ?";  // MySQL/PostgreSQL/HSQL/Interbase
}

Oracle 9i+ 採用三層巢狀查詢配合 `rownum`:

select * from (
    select row_.*, rownum rownum_ from ( 原始SQL ) row_ where rownum <= ?
) where rownum_ > ?

此寫法支援 `ORDER BY`,單/雙層寫法不支援。

策略二:JDBC 2.0 Scrollable ResultSet(次選)

配置 `hibernate.jdbc.use_scrollable_resultset=true`(預設)。

if (session.getFactory().useScrollableResultSets()) {
    rs.absolute(firstRow);  // 直接跳轉到起始行
} else {
    for (int m = 0; m < firstRow; m++) rs.next();  // 逐行移動(慢)
}

策略三:逐行迭代(最後手段)

不支援 Scrollable 時,僅能 `rs.next()` 逐行推進。

核心優勢總結

支援原生分頁的主流方言

  • MySQLDialect:`LIMIT ?, ?`
  • Oracle9Dialect:三層 ROWNUM 巢狀查詢
  • PostgreSQLDialect:`LIMIT ? OFFSET ?`
  • HSQLDialect / InterbaseDialect:類似 LIMIT 語法

最佳實踐建議

  • 大數據量分頁務必設定正確方言,發揮資料庫原生優化
  • 避免深層分頁(如 `setFirstResult(1000000)`),考慮游標/Keyset 分頁
  • 配合 `true` 確保降級路徑可用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
優勢說明
效能最優化優先使用資料庫原生分頁語法
跨資料庫可移植同一代碼無縫切換 MySQL/Oracle/PostgreSQL 等
優雅降級原生不支援 → Scrollable → 迭代,無需業務代碼修改