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

Hibernate 分頁實戰:封裝 Page 對象與工具類實現通用分頁

     編輯:Java 相關知識

前言

Hibernate 原生分頁依賴 setFirstResult() 和 setMaxResults(),但實際項目中需要頁碼導航、總記錄數統計等完整功能。本文提供生產級分頁封裝方案。

核心 API

Query query = session.createQuery("FROM Article WHERE username = ?");
query.setParameter(0, username);
query.setFirstResult(page.getBeginIndex()); // 起始索引 (0-based)
query.setMaxResults(page.getEveryPage());   // 每頁條數
List
list = query.list();

Page 領域模型

public class Page {
    private int everyPage;      // 每頁條數
    private int totalCount;     // 總記錄數
    private int totalPage;      // 總頁數
    private int currentPage;    // 當前頁碼 (1-based)
    private int beginIndex;     // 起始索引 (0-based)
    private boolean hasPrePage; // 是否有上一頁
    private boolean hasNextPage;// 是否有下一頁
    
    // 構造器、getter/setter 省略...
}

PageUtil 計算工具類

public class PageUtil {
    /** 三參構建:每頁條數、總記錄數、當前頁碼 */
    public static Page createPage(int everyPage, int totalCount, int currentPage) {
        everyPage = normalizeEveryPage(everyPage);
        currentPage = normalizeCurrentPage(currentPage);
        int totalPage = calculateTotalPage(everyPage, totalCount);
        int beginIndex = calculateBeginIndex(everyPage, currentPage);
        boolean hasPrePage = currentPage > 1;
        boolean hasNextPage = currentPage < totalPage && totalPage > 0;
        return new Page(everyPage, totalCount, totalPage, currentPage, beginIndex, hasPrePage, hasNextPage);
    }
    
    private static int normalizeEveryPage(int n) { return n <= 0 ? 10 : n; }
    private static int normalizeCurrentPage(int n) { return n <= 0 ? 1 : n; }
    private static int calculateTotalPage(int everyPage, int totalCount) {
        return totalCount % everyPage == 0 ? totalCount / everyPage : totalCount / everyPage + 1;
    }
    private static int calculateBeginIndex(int everyPage, int currentPage) {
        return (currentPage - 1) * everyPage;
    }
}

DAO 層整合示例

public List
queryByPage(String username, Page page) { return getHibernateTemplate().executeFind(session -> { Query query = session.createQuery("FROM Article WHERE username = ?"); query.setParameter(0, username); query.setFirstResult(page.getBeginIndex()); query.setMaxResults(page.getEveryPage()); return query.list(); }); } // Service 層調用 public Page
getArticles(String username, int pageNo, int pageSize) { int totalCount = countByUsername(username); // 先查總數 Page page = PageUtil.createPage(pageSize, totalCount, pageNo); List
list = articleDao.queryByPage(username, page); page.setData(list); // 假設 Page 有 setData 方法 return page; }

前端頁碼導航渲染 (JSP 示例)

<c:if test="${page.hasPrePage}">
    <a href="list.do?pageNo=${page.currentPage - 1}">上一頁</a>
</c:if>
<c:forEach begin="1" end="${page.totalPage}" varStatus="i">
    <c:choose>
        <c:when test="${i.current == page.currentPage}">[${i.current}]</c:when>
        <c:otherwise><a href="list.do?pageNo=${i.current}">${i.current}</a></c:otherwise>
    </c:choose>
</c:forEach>
<c:if test="${page.hasNextPage}">
    <a href="list.do?pageNo=${page.currentPage + 1}">下一頁</a>
</c:if>

性能優化提示

  • 總數查詢優化:大數據量時使用 SELECT COUNT(*) 而非加載所有對象
  • 索引覆蓋:WHERE 條件字段建立索引,避免全表掃描
  • 游標分頁:超大數據集 (百萬級+) 考慮 Keyset Pagination (WHERE id > lastId) 替代 OFFSET
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved