使用Pager在jsp分页,利用ThreadLocal 的特性保证每个线程有唯一的分页信息,且能随时存取。
pager 的缺陷:无法使用post提交请求
1 pager.jsp
maxPageItems 用来计算页数并显示。值为page size
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- 可以直接引taglib 也可以引taglib的jsp页面 如 <%@ include file="taglib.jsp" %> -->
<%@ taglib prefix="pg" uri="http://jsptags.com/tags/navigation/pager" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<pg:pager url="${param.url }" items="${pagerModel.total}" maxPageItems="10" export="currentPageNumber=pageNumber" >
共${pagerModel.total }条记录
<c:forEach items="${param.params }" var="p">
<pg:param name="${p}"/>
</c:forEach>
<pg:first>
<a href="${pageUrl}">首页</a>
</pg:first>
<pg:prev>
<a href="${pageUrl }">上一页</a>
</pg:prev>
<pg:pages>
<c:choose>
<c:when test="${currentPageNumber eq pageNumber}">
<font color="red">${pageNumber }</font>
</c:when>
<c:otherwise>
<a href="${pageUrl }">${pageNumber }</a>
</c:otherwise>
</c:choose>
</pg:pages>
<pg:next>
<a href="${pageUrl }">下一页</a>
</pg:next>
<pg:last>
<a href="${pageUrl }">尾页</a>
</pg:last>
</pg:pager>
2. 列表jsp 中引用 pager.jsp
url 为点击下一页、页数、尾页等访问的链接
params为访问附带的参数,多个用逗号隔开(此参数的值为上一次请求参数的值)
<jsp:include page="/WEB-INF/jsp/common/pager.jsp">
<jsp:param name="url" value="test/list" />
<jsp:param name="params" value="code,name" />
</jsp:include>
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
}
4 PagerThreadLocal.java
用 ThreadLocal 存储 PageModel
public class PagerThreadLocal{
/**
* create the threadLocal
*/
public static ThreadLocal<PageModel> pagerThreadLocal = new ThreadLocal<PageModel>();
/**
* get the pageModel from the threadLocal;<br/>
* 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();
}
}
5,PagerInterceptor.java 拦截器
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
}
将请求参数 放入ParameterPair List中后
7.BaseHibernateDao 中 有如下 hql 分页不分页条件查询方法
/**
* 分页或非分页 条件查询
* @param hql hql语句
* @param paramList ParameterPair List
* @param isPaging true:分页 false:不分页
* @return
*/
public List queryPagingData(String hql, List<ParameterPair> 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();
}
简单的 分页不分页动态查询 在处理完 业务特有的 逻辑后,便可使用此通用查询方法。