public class PaginationSupport{
public final static int PAGESIZE = 30;
private int pageSize = PAGESIZE;
private List items;
private int totalCount;
private int[] indexes = new int[0];
private int startIndex = 0;
public PaginationSupport(List items, int totalCount) {
setPageSize(PAGESIZE);
setTotalCount(totalCount);
setItems(items);
setStartIndex(0);
}
public PaginationSupport(List items, int totalCount, int startIndex) {
setPageSize(PAGESIZE);
setTotalCount(totalCount);
setItems(items);
setStartIndex(startIndex);
}
public PaginationSupport(List items, int totalCount, int pageSize,
int startIndex) {
setPageSize(pageSize);
setTotalCount(totalCount);
setItems(items);
setStartIndex(startIndex);
}
public List getItems() {
return items;
}
public void setItems(List items) {
this.items = items;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
if (totalCount > 0) {
this.totalCount = totalCount;
int count = totalCount / pageSize;
if (totalCount % pageSize > 0)
count++;
indexes = new int[count];
for (int i = 0; i < count; i++) {
indexes[i] = pageSize * i;
}
} else {
this.totalCount = 0;
}
}
public int[] getIndexes() {
return indexes;
}
public void setIndexes(int[] indexes) {
this.indexes = indexes;
}
public int getStartIndex() {
return startIndex;
}
public void setStartIndex(int startIndex) {
if (totalCount <= 0)
this.startIndex = 0;
else if (startIndex >= totalCount)
this.startIndex = indexes[indexes.length - 1];
else if (startIndex < 0)
this.startIndex = 0;
else {
this.startIndex = indexes[startIndex / pageSize];
}
}
public int getNextIndex() {
int nextIndex = getStartIndex() + pageSize;
if (nextIndex >= totalCount)
return getStartIndex();
else
return nextIndex;
}
public int getPreviousIndex() {
int previousIndex = getStartIndex() - pageSize;
if (previousIndex < 0)
return 0;
else
return previousIndex;
}
public int getPageCount() {
int count = totalCount / pageSize;
if (totalCount % pageSize > 0)
count++;
return count;
}
public int getCurentPageNum() {
return getStartIndex() / pageSize + 1;
}
}
在這個分頁類中設(shè)定了每頁要顯示的記錄數(shù)以及開始索引,如果用普通的jsp來取這個分頁類的數(shù)據(jù)還可以,但是使用spring+hibernate這種架構(gòu)就顯得比較麻煩(原因是spring MVC返回的是一個 PaginationSupport的對象,使用jstl作為前端顯示的話,會在jsp頁面中摻雜大量的計算,像下一頁索引,共多少條記錄,當(dāng)前第幾頁,共多少頁等等會使jsp很難維護(hù))下面是對這個類的改進(jìn):
public class PaginationSupport {
public final static int PAGESIZE = 30;
private int pageSize = PAGESIZE;
private int totalCount;
private int currentPage;
private int startIndex;
private int[] indexes = new int[0];
private int nextIndex;
private int previousIndex;
private int pageCount;
private List items;
private int lastIndex;
public PaginationSupport(int pageSize,
int startIndex) {
setPageSize(pageSize);
setStartIndex(startIndex);
}
public PaginationSupport(List items, int totalCount) {
setPageSize(PAGESIZE);
setTotalCount(totalCount);
setItems(items);
setStartIndex(0);
}
public PaginationSupport(List items, int totalCount, int startIndex) {
setPageSize(PAGESIZE);
setTotalCount(totalCount);
setItems(items);
setStartIndex(startIndex);
}
public PaginationSupport(List items, int totalCount, int pageSize,
int startIndex) {
setPageSize(pageSize);
setTotalCount(totalCount);
setItems(items);
setStartIndex(startIndex);
}
public void setTotalCount(int totalCount) {
if (totalCount > 0) {
this.totalCount = totalCount;
int count = totalCount / pageSize;
if (totalCount % pageSize > 0)
count++;
indexes = new int[count];
for (int i = 0; i < count; i++) {
indexes[i] = pageSize * i;
}
} else {
this.totalCount = 0;
}
}
public int getTotalCount() {
return totalCount;
}
public void setIndexes(int[] indexes) {
this.indexes = indexes;
}
public int[] getIndexes() {
return indexes;
}
public void setStartIndex(int startIndex) {
if (totalCount <= 0)
this.startIndex = 0;
else if (startIndex >= totalCount)
this.startIndex = indexes[indexes.length - 1];
else if (startIndex < 0)
this.startIndex = 0;
else {
this.startIndex = indexes[startIndex / pageSize];
}
}
public int getStartIndex() {
return startIndex;
}
public void setNextIndex(int nextIndex) {
this.nextIndex = nextIndex;
}
public int getNextIndex() {
int nextIndex = getStartIndex() + pageSize;
if (nextIndex >= totalCount)
return getStartIndex();
else
return nextIndex;
}
public void setPreviousIndex(int previousIndex) {
this.previousIndex = previousIndex;
}
public int getPreviousIndex() {
int previousIndex = getStartIndex() - pageSize;
if (previousIndex < 0)
return 0;
else
return previousIndex;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public int getPageCount() {
int count = totalCount / pageSize;
if (totalCount % pageSize > 0)
count++;
return count;
}
public int getCurrentPage() {
return getStartIndex() / pageSize + 1;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public void setLastIndex(int lastIndex) {
this.lastIndex =lastIndex ;
}
public int getLastIndex() {
return indexes[indexes.length-1];
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public List getItems() {
return items;
}
public void setItems(List items) {
this.items = items;
}
}
以上是分頁的封裝類,下面是支持分頁查詢的方法:
1)
public PaginationSupport findPageByCriteria(
final DetachedCriteria detachedCriteria, final int pageSize,
final int startIndex) {
return (PaginationSupport) getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
Criteria criteria = detachedCriteria
.getExecutableCriteria(session);
int totalCount = ((Integer) criteria.setProjection(
Projections.rowCount()).uniqueResult())
.intValue();
criteria.setProjection(null);
List items = criteria.setFirstResult(startIndex)
.setMaxResults(pageSize).list();
PaginationSupport ps = new PaginationSupport(items,
totalCount, pageSize, startIndex);
return ps;
}
}, true);
}
2)
public PaginationSupport findPageByQuery( final String hsql, final int pageSize,final int startIndex){
return (PaginationSupport)getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createQuery(hsql);
int totalCount=query.list().size();
query.setFirstResult(startIndex);
query.setMaxResults(pageSize);
List items = query.list();
PaginationSupport ps = new PaginationSupport(items,
totalCount, pageSize, startIndex);
return ps;
}
},true);
}
你也許會問分頁查詢?yōu)槭裁磿峁﹥蓚€方法,這兩個方法有區(qū)別嗎?其實這兩個方法并無本質(zhì)區(qū)別,DetachedCriteria 也是構(gòu)造查詢語句的與Query功能一致,但是它提供了更加面向?qū)ο蟮姆椒▉韺慼sql語句。一般人們都傾向第一種方法,但是這種方法并不通用,它有一種查詢并不支持,那就是當(dāng)你要查詢的對象并不是一個單一對象的話(例如 你在數(shù)據(jù)庫中有兩個表,一個是user,另一個是userinfo,這兩個表所對應(yīng)的對象在hiberante中被指定為共享主鍵的話,在執(zhí)行查詢的時候就會報類型轉(zhuǎn)換異常,原因是查詢出來的對象并不是user而是一個包含user 和userinfo的Object,你若強(qiáng)制把它轉(zhuǎn)換成user類型,肯定會出錯),這時你不得不采用第二個方法。當(dāng)然這只是我個人見解,也許還有地方說的不是很準(zhǔn)確,希望大家多多批評指正。
最后是這個分頁類的前臺顯示源代碼:
<%@ page language="java" contentType="text/html; charset=gbk"
pageEncoding="GBK"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link type="text/css" rel="stylesheet" href="../css/panel.css">
<title>顯示所有用戶</title>
</head>
<body>
<div style="margin:20px auto 30px; width:70%;"><a href="index.jsp" class="btn2">返回首頁</a></div>
<div style="margin:10px auto 0; width:70%;">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<caption>
顯示所有用戶
</caption>
<tr>
<td>用戶ID</td>
<td>用戶名</td>
<td>用戶昵稱</td>
<td>電子郵件</td>
<td>注冊時間</td>
<td>詳細(xì)信息</td>
<td>用戶充值記錄</td>
<td>用戶定制服務(wù)信息</td>
</tr>
<c:forEach var="user" items="${userPage.items}">
<tr>
<td>${user.intId}</td>
<td>${user.username}</td>
<td>${user.name}</td>
<td>${user.email}</td>
<td><fmt:formatDate value='${user.creationTime}' pattern='yyyy-MM-dd HH:mm' /></td>
<td><a href="user_getdetailUser.ado?userId=${user.intId}" class="btn">詳細(xì)信息</a></td>
<td><a href="orderService_getUserAccountAdds.ado?userId=${user.intId}" class="btn">用戶充值記錄</a></td>
<td><a href="orderService_getUserChargeItems.ado?userId=${user.intId}" class="btn">用戶定制服務(wù)信息</a></td>
</tr>
</c:forEach>
</table>
<c:if test="${!empty userPage}">
共${userPage.totalCount}記錄
<c:choose>
<c:when test="${userPage.startIndex ne '0'}">
<a href="user_getPage.ado?startIndex=0">首頁</a>
</c:when>
<c:otherwise>
首頁
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${userPage.previousIndex lt userPage.startIndex}">
<a href="user_getPage.ado?startIndex=${userPage.previousIndex }">上一頁</a>
</c:when>
<c:otherwise>
上一頁
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${userPage.nextIndex>userPage.startIndex}">
<a href="user_getPage.ado?startIndex=${userPage.nextIndex}">下一頁</a>
</c:when>
<c:otherwise>
下一頁
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${userPage.lastIndex eq userPage.startIndex}">
最后一頁
</c:when>
<c:otherwise>
<a href="user_getPage.ado?startIndex=${userPage.lastIndex}">最后一頁</a>
</c:otherwise>
</c:choose>
每頁顯示${userPage.pageSize}條記錄
當(dāng)前第${userPage.currentPage }/${userPage.pageCount}頁
</c:if>
</div>
</body>
</html>