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 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为访问附带的参数,多个用逗号隔开(此参数的值为上一次请求参数的值)


	
	


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

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

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

你可能感兴趣的:(hibernate)