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

Hibernate 分頁查詢的兩種核心實現方式深度解析

     編輯:Java 相關知識

前言

在企業級 Java 開發中,數據分頁是極為常見的需求。Hibernate 作為經典的 ORM 框架,提供了多種分頁實現路徑。本文將深入剖析 Criteria API 與 HQL 兩大主流分頁方案的核心代碼、原理差異及適用場景,幫助開發者根據業務複雜度做出最優技術選型。

方案一:基於 Criteria API 的物件導向分頁

Criteria API 以強類型、物件導向的方式構建查詢,適合動態條件組合場景。其分頁核心邏輯包含三步:

  1. 設置投影獲取總記錄數(Projections.rowCount())
  2. 清除投影,設置起始位置(setFirstResult)與最大結果數(setMaxResults)
  3. 封裝分頁結果對象(當前頁、頁大小、總記錄數、數據列表)

核心代碼示例

public Page getPage(int currentPage, int pageSize, Criterion... crts) {
    Criteria criteria = session.createCriteria(House.class);
    
    // 動態添加查詢條件
    for (Criterion criterion : crts) {
        criteria.add(criterion);
    }
    
    // 1. 查詢總記錄數
    criteria.setProjection(Projections.rowCount());
    int totalRecord = Integer.valueOf(criteria.uniqueResult().toString());
    
    // 2. 執行分頁查詢
    criteria.setProjection(null); // 必須清除投影
    criteria.setFirstResult((currentPage - 1) * pageSize);
    criteria.setMaxResults(pageSize);
    List list = criteria.list();
    
    // 3. 封裝分頁對象
    Page page = new Page();
    page.setCurrentPage(currentPage);
    page.setPageSize(pageSize);
    page.setTotalRecord(totalRecord);
    page.setList(list);
    return page;
}

關鍵優勢與注意點

  • 類型安全:編譯期檢查屬性名,重構友好
  • 動態組裝:極適合多條件可選查詢(如電商篩選)
  • 投影切換:統計總數與查數據需分離設置投影,易遺漏 setProjection(null)

方案二:基於 HQL 的靈活分頁

HQL 接近 SQL 風格,適合複雜關聯查詢、自定義選列等場景。分頁邏輯同樣遵循「先查總數、後查數據」模式,但需手動構建計數 HQL。

核心代碼示例

public Page getPage(int currentPage, int pageSize, String hql, Object... args) {
    // 1. 構建計數 HQL:從 from 關鍵字截取
    String countHql = "select count(*) " + hql.substring(hql.indexOf("from"));
    
    Session session = HibernateUtil.getInstance().getSession();
    
    // 2. 查詢總記錄數
    Query countQuery = session.createQuery(countHql);
    for (int i = 0; i < args.length; i++) {
        countQuery.setParameter(i, args[i]);
    }
    int totalRecord = Integer.valueOf(countQuery.uniqueResult() + "");
    
    // 3. 執行分頁查詢
    Query dataQuery = session.createQuery(hql);
    for (int i = 0; i < args.length; i++) {
        dataQuery.setParameter(i, args[i]);
    }
    dataQuery.setFirstResult(pageSize * (currentPage - 1));
    dataQuery.setMaxResults(pageSize);
    List<House> list = (List<House>) dataQuery.list();
    
    // 4. 封裝結果
    Page page = new Page();
    page.setCurrentPage(currentPage);
    page.setPageSize(pageSize);
    page.setTotalRecord(totalRecord);
    page.setList(list);
    return page;
}

關鍵優勢與注意點

  • SQL 親和力:複雜關聯、子查詢、分組統計表達自然
  • 參數綁定:位置參數(?)或命名參數(:name)防注入
  • 計數 HQL 構建:單純 substring 易失效(如含子查詢),建議用解析器或手寫計數語句

兩大方案對比與選型建議

維度Criteria APIHQL
類型安全✅ 編譯期檢查❌ 運行期報錯
動態條件✅ 極佳⚠️ 字符串拼接繁瑣
複雜查詢⚠️ API 複雜✅ 靈活強大
維護成本低(重構友好)高(字符串易出錯)
適用場景後台管理、多條件篩選報表統計、複雜業務邏輯

最佳實踐總結

  1. 統一封裝:將分頁邏輯抽象為通用 BaseDao 方法,業務層僅傳參
  2. 參數校驗:頁碼、頁大小邊界檢查,防止非法值導致異常
  3. 性能優化:大數據量場景考慮「延遲關聯」或「專用計數表」避免全表掃描
  4. 遷移建議:Hibernate 5.2+ 已废弃 Criteria API,新項目推薦 JPA CriteriaBuilder 或 QueryDSL

掌握這兩種分頁核心模式,能讓你在面對不同業務複雜度時,游刃有餘地實現高性能、可維護的分頁查詢功能。

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