Hibernate 原生分頁依賴 setFirstResult() 和 setMaxResults(),但實際項目中需要頁碼導航、總記錄數統計等完整功能。本文提供生產級分頁封裝方案。
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();
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 省略...
}
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;
}
}
public ListqueryByPage(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; }
<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(*) 而非加載所有對象