Query q = session.createQuery("from Cat as c");
q.setFirstResult(20000); // 從第 20001 筆開始
q.setMaxResults(100); // 取 100 筆
List l = q.list();
Hibernate 根據資料庫方言採用三層降級策略:
// 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`,單/雙層寫法不支援。
配置 `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()` 逐行推進。
| 優勢 | 說明 |
|---|---|
| 效能最優化 | 優先使用資料庫原生分頁語法 |
| 跨資料庫可移植 | 同一代碼無縫切換 MySQL/Oracle/PostgreSQL 等 |
| 優雅降級 | 原生不支援 → Scrollable → 迭代,無需業務代碼修改 |