花了两天时间才整理好的分页类,共享一下。
说明:该方法是参考了一下网上广为流传的DetachedCriteria查询方法后改进而来的。按照自己觉得满意的方法去修改了一下。并且配合struts1.2的标记配合使用,其实应该直接封装成自己分页标记的,或者使用JavaScript生成,但先这样吧,当作学习struts的标记库使用。
按钮的效果可以简单的做到附件图片上的效果
[img]/upload/attachment/88621/e8428bff-447a-38f7-b337-446ac9be003e.jpg[/img]
虽然不敢说完美的分页按钮,但比较满意的效果了。
------------------------------------
分页Bean类:
----------------------
DAO层,其实不需要局限用Criteria查询的。查询好需要的数据后,构造bean类,如下。
1. PaginationSupport ps = new PaginationSupport(items,
2. totalCount, pageSize, startIndex,
3. detachedCriteria);
附上完整的DetachedCriteria查询方法供参考。在网上找到的,然后参考改进了一下,因为找到的都存在BUG,下面是修正后的版本。测试,并且正常使用中。
----------------------
view层使用struts标签,代码有点长,供参考。注意css效果。
注意,action的方法其实需要两个即可,一个是第一次搜索的时候查询方法。另外一个是跳转到任何一页的方法。就算向前向后这样的方法其实并不需要。
说明:该方法是参考了一下网上广为流传的DetachedCriteria查询方法后改进而来的。按照自己觉得满意的方法去修改了一下。并且配合struts1.2的标记配合使用,其实应该直接封装成自己分页标记的,或者使用JavaScript生成,但先这样吧,当作学习struts的标记库使用。
按钮的效果可以简单的做到附件图片上的效果
[img]/upload/attachment/88621/e8428bff-447a-38f7-b337-446ac9be003e.jpg[/img]
虽然不敢说完美的分页按钮,但比较满意的效果了。
------------------------------------
分页Bean类:
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
/**
* 分页常用的bean类。<br>
* 里面包含搜索返回的List,查询条件DetachedCriteria及分页菜单用到的数据等。
*
* @author KennyLee E-mail:kennylee26@gmail.com 2008-10-25
*/
public class KPaginationSupport implements Cloneable {
// Default page size
public static final int PAGESIZE = 20;
public static final int MENU_SIZE = 7;
// total Rows
private int totalRowsAmount;
private int pageSize = PAGESIZE;
private int totalPages;
// current page number
private int currentPage = 1;
// next page number
private int nextPage;
// previous page number
private int previousPage;
// is has next page
private boolean hasNext;
// is has previous page
private boolean hasPrevious;
// current page start row number
private int pageStartRow = 0;
// current page end row number
private int pageEndRow;
private String[] pageMenuNum;
private int menuSize = MENU_SIZE;
// Pagination values
private List items;
// select detachedCriteria
private DetachedCriteria detachedCriteria;
public KPaginationSupport() {
}
public String[] getPageMenuNum() {
return pageMenuNum;
}
public void setPageMenuNum(String[] pageMenuNum) {
this.pageMenuNum = pageMenuNum;
}
public DetachedCriteria getDetachedCriteria() {
return detachedCriteria;
}
public void setDetachedCriteria(DetachedCriteria detachedCriteria) {
this.detachedCriteria = detachedCriteria;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public void setNextPage(int nextPage) {
this.nextPage = nextPage;
}
public void setPreviousPage(int previousPage) {
this.previousPage = previousPage;
}
public void setHasNext(boolean hasNext) {
this.hasNext = hasNext;
}
public void setHasPrevious(boolean hasPrevious) {
this.hasPrevious = hasPrevious;
}
public void setPageStartRow(int pageStartRow) {
this.pageStartRow = pageStartRow;
}
public List getItems() {
return items;
}
public void setItems(List items) {
this.items = items;
}
public void setPageEndRow(int pageEndRow) {
this.pageEndRow = pageEndRow;
}
/**
* 构造函数。
*
* @param totalRows
* 总行数
* @param currentPage
* 当前页数
*/
public KPaginationSupport(int totalRows, int currentPage) {
setPaginationSupport(totalRows, currentPage);
}
/**
* 构造函数。
*
* @param totalRows
* 总行数
* @param currentPage
* 当前页数
* @param pageSize
* 每页显示数量。
*/
public KPaginationSupport(int totalRows, int currentPage, int pageSize) {
this.pageSize = pageSize;
this.setPaginationSupport(totalRows, currentPage);
String[] pageNums = getPageMenuNums(currentPage);
this.setPageMenuNum(pageNums);
}
public void setPaginationSupport(int totalRows, int currentPage) {
// 获取总页码,通过对象总数还是每页多少行的关系
setTotalRowsAmount(totalRows);
setCurrentPage(currentPage);
}
public KPaginationSupport(List items, int totalCount) {
setPageSize(PAGESIZE);
setItems(items);
int currentPage = 1;
this.setPaginationSupport(totalCount, currentPage);
}
public KPaginationSupport(List items, int totalCount, int startIndex) {
setPageSize(PAGESIZE);
setItems(items);
int currentPage = (startIndex / pageSize) + 1;
this.setPaginationSupport(totalCount, currentPage);
}
/**
* @param items
* 保存的目标List
* @param totalCount
* 查找的总行数
* @param pageSize
* 每页显示的行数
* @param startIndex
* 第几行开始
*
*/
public KPaginationSupport(List items, int totalCount, int pageSize,
int startIndex) {
setPageSize(pageSize);
setItems(items);
int currentPage = (startIndex / pageSize) + 1;
this.setPaginationSupport(totalCount, currentPage);
}
/**
*
* 构造PS时的初始化方法。
*
* @param items
* 保存的目标List
* @param totalCount
* 查找的总行数
* @param pageSize
* 每页显示的行数
* @param startIndex
* 第几行开始
*
*/
public KPaginationSupport(List items, int totalCount, int pageSize,
int startIndex, DetachedCriteria detachedCriteria) {
setPageSize(pageSize);
setItems(items);
int currentPage = (startIndex / pageSize) + 1;
this.setPaginationSupport(totalCount, currentPage);
setDetachedCriteria(detachedCriteria);
String[] pageNums = getPageMenuNums(currentPage);
this.setPageMenuNum(pageNums);
}
/**
* 分页导航按钮
*
* @param currentPage
* @return
*/
private String[] getPageMenuNums(int currentPage) {
String[] pageNums = null;
if (totalPages > menuSize) {// 总页数大于导航显示的页数
pageNums = new String[menuSize];
int lastMenuNum = totalPages - menuSize + 1;// 最后一列导航栏按钮
int beginMumNum = menuSize;
int x = menuSize - 1;// 导航显示系数
if ((currentPage < lastMenuNum) && (currentPage > beginMumNum)) {
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(currentPage + i - x / 2);
}
} else if (currentPage > lastMenuNum) {
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(lastMenuNum + i);
}
} else if (currentPage == lastMenuNum) {
if ((lastMenuNum - x / 2) < 1) {
lastMenuNum = x / 2 + 1;
}
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(lastMenuNum + i - x / 2);
}
} else if (currentPage == beginMumNum) {
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(1 + i + x / 2);
}
} else {
for (int i = 0; i < menuSize; i++) {
pageNums[i] = String.valueOf(1 + i);
}
}
} else {// 总页数小于等于导航显示的页数,直接显示。
pageNums = new String[totalPages];
// 分页数比总页数少
for (int i = 0; i < totalPages; i++) {
pageNums[i] = String.valueOf(i + 1);
}
}
return pageNums;
}
/**
* 设置总行数。
*
* @param rows
* 总行数。
*/
private void setTotalRowsAmount(int rows) {
if (rows < 0) {
totalRowsAmount = 0;
} else {
totalRowsAmount = rows;
}
if (totalRowsAmount % pageSize == 0) {
totalPages = totalRowsAmount / pageSize;
} else {
totalPages = totalRowsAmount / pageSize + 1;
}
}
/**
*设置当前页数。
*
* @param curPage
*/
private void setCurrentPage(int curPage) {
if (curPage <= 0) {
currentPage = 1;
} else if (curPage > totalPages) {
currentPage = totalPages;
} else {
currentPage = curPage;
}
if (currentPage == 1) {
hasPrevious = false;
} else {
hasPrevious = true;
}
if (currentPage == totalPages) {
hasNext = false;
} else {
hasNext = true;
}
nextPage = currentPage + 1;
previousPage = currentPage - 1;
// 计算当前页开始行和结束行
pageStartRow = (currentPage - 1) * pageSize + 1;
// pageStartRow = (currentPage - 1) * pageSize;
// 记录索引从0开始
pageStartRow -= 1;
pageEndRow = pageStartRow + pageSize;
}
public int getCurrentPage() {
return currentPage;
}
public boolean isHasNext() {
return hasNext;
}
public boolean isHasPrevious() {
return hasPrevious;
}
public int getNextPage() {
return nextPage;
}
public int getPageSize() {
return pageSize;
}
public int getPreviousPage() {
return previousPage;
}
public int getTotalPages() {
return totalPages;
}
public int getTotalRowsAmount() {
return totalRowsAmount;
}
public int getPageStartRow() {
return pageStartRow;
}
public int getPageEndRow() {
return pageEndRow;
}
public String description() {
String description = "Total:" + this.getTotalRowsAmount() + " items "
+ this.getTotalPages() + " pages,Current page:"
+ this.currentPage + " Previous " + this.hasPrevious + " Next:"
+ this.hasNext + " start row:" + this.pageStartRow
+ " end row:" + this.pageEndRow;
return description;
}
public void init() {
// do some initialization work
}
@Override
public KPaginationSupport clone() throws CloneNotSupportedException {
return (KPaginationSupport) super.clone();
}
public int getMenuSize() {
return menuSize;
}
public void setMenuSize(int menuSize) {
this.menuSize = menuSize;
}
}
----------------------
DAO层,其实不需要局限用Criteria查询的。查询好需要的数据后,构造bean类,如下。
1. PaginationSupport ps = new PaginationSupport(items,
2. totalCount, pageSize, startIndex,
3. detachedCriteria);
附上完整的DetachedCriteria查询方法供参考。在网上找到的,然后参考改进了一下,因为找到的都存在BUG,下面是修正后的版本。测试,并且正常使用中。
/**
* @param detachedCriteria
* @param pageSize
* @param startIndex
*/
public PaginationSupport findPageByCriteria(
final DetachedCriteria detachedCriteria, final int pageSize,
final int startIndex) {
log.info("in findByPage...");
return (PaginationSupport) getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException {
Criteria criteria = detachedCriteria
.getExecutableCriteria(session);
CriteriaImpl impl = (CriteriaImpl) criteria;
// 先把Projection和OrderBy条件取出来,清空两者来执行Count操作
Projection projection = impl.getProjection();
int totalCount = ((Integer) criteria.setProjection(
Projections.rowCount()).uniqueResult())
.intValue();
log.info("totalCount:" + totalCount);
// 将之前的Projection和OrderBy条件重新设回去
criteria.setProjection(projection);
if (projection == null) {
criteria
.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
}
List items = criteria.setFirstResult(startIndex)
.setMaxResults(pageSize).list();
PaginationSupport ps = new PaginationSupport(items,
totalCount, pageSize, startIndex,
detachedCriteria);
// Set default status
criteria.setFirstResult(0).setMaxResults(totalCount);
return ps;
}
});
}
----------------------
view层使用struts标签,代码有点长,供参考。注意css效果。
注意,action的方法其实需要两个即可,一个是第一次搜索的时候查询方法。另外一个是跳转到任何一页的方法。就算向前向后这样的方法其实并不需要。
<!-- pagination menu begin by KennyLee 2008-9-16 -->
<logic:present name="pageController" scope="request">
<tr>
<td colspan="6">
<div id="pagination_info">
[共${pageController.totalRowsAmount} 个账号] ${pageController.currentPage}/${pageController.totalPages}页(每页显示${pageController.pageSize})
</div>
<div class="pagination">
<logic:equal value="true" name="pageController"
property="hasPrevious">
<html:link action="/mailbox/controller/list/pre"
paramId="toPageGo" paramName="pageController"
paramProperty="previousPage"><Perv</html:link>
</logic:equal>
<logic:notEqual value="true" name="pageController"
property="hasPrevious">
<span class="disabled"><Perv</span>
</logic:notEqual>
<logic:iterate id="num" name="pageController"
property="pageMenuNum" indexId="index">
<logic:equal value="0" name="index">
<logic:equal value="2" name="num">
<html:link
page="/mailbox/controller/list/current.jspx?toPageGo=1">1</html:link>
</logic:equal>
<logic:greaterThan value="2" name="num">
<html:link
page="/mailbox/controller/list/current.jspx?toPageGo=1">1</html:link>
<span>...</span>
</logic:greaterThan>
</logic:equal>
<logic:equal value="${num}" property="currentPage"
name="pageController">
<span class="current">${pageController.currentPage}</span>
</logic:equal>
<logic:notEqual value="${num}" property="currentPage"
name="pageController">
<html:link
page="/mailbox/controller/list/current.jspx?toPageGo=${num}">${num}</html:link>
</logic:notEqual>
<logic:equal value="${pageController.menuSize-1}"
name="index">
<logic:equal value="${pageController.totalPages-1}"
name="num">
<html:link
page="/mailbox/controller/list/current.jspx?toPageGo=${pageController.totalPages}">${pageController.totalPages}</html:link>
</logic:equal>
<logic:lessThan value="${pageController.totalPages-1}"
name="num">
<span>...</span>
<html:link
page="/mailbox/controller/list/current.jspx?toPageGo=${pageController.totalPages}">${pageController.totalPages}</html:link>
</logic:lessThan>
</logic:equal>
</logic:iterate>
<logic:equal value="true" name="pageController"
property="hasNext">
<html:link action="/mailbox/controller/list/next"
paramId="toPageGo" paramName="pageController"
paramProperty="nextPage">Next></html:link>
</logic:equal>
<logic:notEqual value="true" name="pageController"
property="hasNext">
<span class="disabled">Next></span>
</logic:notEqual>
</div>
</td>
</tr>
</logic:present>
<!-- pagination menu end -->