使用Pager在jsp分页,利用ThreadLocal 的特性保证每个线程有唯一的分页信息,且能随时存取。
pager 的缺陷:无法使用post提交请求
1 pager.jsp
maxPageItems 用来计算页数并显示。值为page size
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
共${pagerModel.total }条记录
首页
上一页
${pageNumber }
${pageNumber }
下一页
尾页
2. 列表jsp 中引用 pager.jsp
url 为点击下一页、页数、尾页等访问的链接
params为访问附带的参数,多个用逗号隔开(此参数的值为上一次请求参数的值)
public class PageModel {
public static final int OFFSET = 0;
public static final int PAGE_SIZE = 10;
/**
* 总记录数
*/
private int total;
private int offset = OFFSET;
private int pageSize = PAGE_SIZE;
public PageModel() {
}
public PageModel(int offset, int pageSize) {
this.offset = offset;
this.pageSize = pageSize;
}
//省略 getter setter
}
用 ThreadLocal 存储 PageModel
public class PagerThreadLocal{
/**
* create the threadLocal
*/
public static ThreadLocal pagerThreadLocal = new ThreadLocal();
/**
* get the pageModel from the threadLocal;
* if the pageModel is null, create a new pageModel
* @return
*/
public static PageModel getPageModel(){
return pagerThreadLocal.get() == null ? new PageModel() : pagerThreadLocal.get();
}
/**
* set the pageModel to the threadLocal
* @param pageModel
*/
public static void setPageModel(PageModel pageModel){
pagerThreadLocal.set(pageModel);
}
/**
* when the request is over, remove the pageModel from threadLocal
*/
public static void remove(){
pagerThreadLocal.remove();
}
}
public class PagerInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
int offset = 0;
try {
offset = Integer.parseInt(request.getParameter("pager.offset"));
} catch (NumberFormatException e) {
}
PageModel pageModel = PagerThreadLocal.getPageModel();
pageModel.setOffset(offset);
PagerThreadLocal.setPageModel(pageModel);
return super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
request.setAttribute("pagerModel", PagerThreadLocal.getPageModel());
super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
PagerThreadLocal.remove();
super.afterCompletion(request, response, handler, ex);
}
}
6. 存放HQL占位符键值对
public class ParameterPair {
/**
* 占位符参数的名字
*/
private String paramName;
/**
* 占位符参数的值
*/
private Object paramValue;
public ParameterPair() {
}
public ParameterPair(String paramName, Object paramValue) {
this.paramName = paramName;
this.paramValue = paramValue;
}
//省略 getter setter
}
7.BaseHibernateDao 中 有如下 hql 分页不分页条件查询方法
/**
* 分页或非分页 条件查询
* @param hql hql语句
* @param paramList ParameterPair List
* @param isPaging true:分页 false:不分页
* @return
*/
public List queryPagingData(String hql, List paramList, boolean isPaging) {
Query query = this.getSession().createQuery(hql);
//分页
if (isPaging) {
String countHql = "SELECT COUNT(*) " + hql;
Query countQuery = this.getSession().createQuery(countHql);
if (paramList != null) {
for (ParameterPair pair : paramList) {
countQuery.setParameter(pair.getParamName(), pair.getParamValue());
query.setParameter(pair.getParamName(), pair.getParamValue());
}
}
int total = Integer.parseInt(countQuery.uniqueResult().toString());
PageModel pageModel = PagerThreadLocal.getPageModel();
pageModel.setTotal(total);
query.setFirstResult(pageModel.getOffset()); //注意Hibernate分页要从开始记录的上一条记录开始取
query.setMaxResults(pageModel.getPageSize());
} else {
if (paramList != null) {
for (ParameterPair pair : paramList) {
query.setParameter(pair.getParamName(), pair.getParamValue());
}
}
}
return query.list();
}