ThreadLocal Pager 分页的一种解决方案 (hibernate)

使用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>


3. PageModel.java 分页实体

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();
	}

简单的 分页不分页动态查询 在处理完 业务特有的 逻辑后,便可使用此通用查询方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值