首先谈谈一些实现的思想:
1、实现分页主要需要向后台的DAO层传递两个参数:PageOffset(PageIndex)和PageSize,其中PageSize可以在后台中指定,比如可以再Filter的配置文件中带上初始化参数,PageOffset(PageIndex)是必须传递的参数;
2、ThreadLocal的作用:在前台和后台共享PageOffset(PageIndex)参数;
3、Filter的作用:拦截前台页面传递过来的参数,并且把得到的参数值放进ThreadLocal中,进而后台进行数据库查询的时候就可以使用ThreadLocal中的参数(也就是前台传递过来的参数);
4、需要穿件一个Pager对象,来包含PageIndex、pageSize、totalpage、totalItem、List<T>;
5、前台的页面根据传递过来的Pager对象进行分页:
方式A:自己简单的写一个分页:
方式B:使用pager-taglib框架:(参照一些项目)在使用Filter拦截获取参数的时候,http://localhost:8080/testPager/PageTagLib.jsp?pager.offset=0&pageIndex=20,必须首先获取pager.offset这个参数,当时是先获取PageIndex,导致pager.offset这个参数一直不能得到,相当蛋疼!!!
1建立LocalThread类,对分页的常数进行封装
代码如下
- package com.tgb.oa;
- /**
- *
- * 采用ThreadLocal来存储分页变量.
- * @author jnqqls
- * @group TGB
- * @version 1.0
- * @comments
- */
- public class SystemContext {
- private static ThreadLocal offset = new ThreadLocal();
- private static ThreadLocal pagesize = new ThreadLocal();
- /**
- * 从线程中获取offset字段
- * @return
- */
- public static int getOffset(){
- Integer os = (Integer)offset.get();
- if(os == null){
- return 0;
- }
- return os;
- }
- public static void setOffset(int offsetvalue){
- offset.set(offsetvalue);
- }
- public static void removeOffset(){
- offset.remove();
- }
- public static int getPagesize(){
- Integer ps = (Integer)pagesize.get();
- if(ps == null){
- return Integer.MAX_VALUE;
- }
- return ps;
- }
- public static void setPagesize(int pagesizevalue){
- pagesize.set(pagesizevalue);
- }
- public static void removePagesize(){
- pagesize.remove();
- }
- }
2建立PagerFilter过滤器,将参数读取到ThreadLocal中.
代码如下:
- <span style="font-size:18px;"> package com.tgb.oa.web;
- import java.io.IOException;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletRequest;
- import com.tgb.oa.SystemContext;
- /**
- *
- * @oa_02 过滤器,获取相关分页数据.
- * @author jnqqls
- * @group TGB
- * @version 1.0
- * @comments
- */
- public class PagerFilter implements Filter {
- public void destroy() {
- }
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- HttpServletRequest httpRequest = (HttpServletRequest)request;
- SystemContext.setOffset(getOffset(httpRequest));
- SystemContext.setPagesize(getPagesize(httpRequest));
- try{
- chain.doFilter(request, response);
- }finally{
- //清空ThreadLocal中的值,避免类的溢出.
- SystemContext.removeOffset();
- SystemContext.removePagesize();
- }
- }
- protected int getOffset(HttpServletRequest request){
- int offset = 0;
- try {
- offset = Integer.parseInt(request.getParameter("pager.offset"));
- } catch (NumberFormatException ignore) {
- }
- return offset;
- }
- protected int getPagesize(HttpServletRequest request){
- return 10;
- }
- public void init(FilterConfig arg0) throws ServletException {
- }
- }
- </span>
3配置filter在WEB.XML文件中
代码如下:
- <span style="font-size:18px;"> <!-- 定义分页Filter -->
- <filter>
- <filter-name>PagerFilter</filter-name>
- <filter-class>com.tgb.oa.web.PagerFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>PagerFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- </span>
4建立抽象类,将分页功能抽象成一个方案,可以在更多的场合下进行运用.
代码如下:
- <span style="font-size:18px;"> package com.tgb.oa.manager.impl;
- import java.util.List;
- import org.hibernate.Query;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- import com.tgb.oa.PagerModel;
- import com.tgb.oa.SystemContext;
- import com.tgb.oa.manager.SystemException;
- /**
- *
- * 抽象分页查询.
- * @author jnqqls
- * @group TGB
- * @version 1.0
- * @comments
- */
- public class AbstractManager extends HibernateDaoSupport {
- public PagerModel searchPaginated(String hql){
- return searchPaginated(hql,null,SystemContext.getOffset(),SystemContext.getPagesize());
- }
- public PagerModel searchPaginated(String hql,Object param){
- return searchPaginated(hql,new Object[]{param},SystemContext.getOffset(),SystemContext.getPagesize());
- }
- public PagerModel searchPaginated(String hql,Object[] params){
- return searchPaginated(hql,params,SystemContext.getOffset(),SystemContext.getPagesize());
- }
- /**
- * 没有参数
- * @param hql
- * @param offset
- * @param pagesize
- * @return
- */
- public PagerModel searchPaginated(String hql,int offset,int pagesize){
- return searchPaginated(hql,null,offset,pagesize);
- }
- /**
- * 只有一个参数
- * @param hql
- * @param obj
- * @param offset
- * @param pagesize
- * @return
- */
- public PagerModel searchPaginated(String hql,Object obj,int offset,int pagesize){
- return searchPaginated(hql,new Object[]{obj},offset,pagesize);
- }
- /**
- * 根据hql语句进行分页查询
- * @param hql
- * @param params HQL语句带的多个参数值.
- * @param offset 从第几条记录开始查询
- * @param pagesize 总共要显示的页数.
- * @return
- */
- public PagerModel searchPaginated(String hql,Object[] params,int offset,int pagesize){
- //第一步:获取总记录数.
- //获取总数的查询语句
- String countHql=getCountQuery(hql);
- //创建查询对象.
- Query query =getSession().createQuery(countHql);
- //通过循环将参数设置到语句中.
- if(params != null && params.length>0){
- for(int i=0;i<params.length;i++){
- query.setParameter(i, params[i]);
- }
- }
- //获取总的记录数
- int total = ((Long)query.uniqueResult()).intValue();
- //获取当前的结果集
- query = getSession().createQuery(hql);
- if(params != null && params.length>0){
- for(int i=0;i<params.length;i++){
- query.setParameter(i, params[i]);
- }
- }
- //设置参数
- query.setFirstResult(offset);
- query.setMaxResults(pagesize);
- //获取结果集.
- List datas=query.list();
- //创建PagerModel对象.
- PagerModel pm = new PagerModel();
- pm.setDatas(datas);
- pm.setTotal(total);
- return pm;
- }
- /**
- * 根据HQL语句,获得查找总记录数的HQL语句.
- * @param hql
- * @return
- */
- private String getCountQuery(String hql) {
- //根据from字截取查询语句.
- int index = hql.indexOf("from");
- if(index != -1){
- return "select count(*) " + hql.substring(index);
- }
- throw new SystemException("无效的HQL查询语句!");
- }
- }
- </span>
5实现抽象类,完成方法的调用.
代码如下:
- <span style="font-size:18px;"> package com.tgb.oa.manager.impl;
- import java.util.List;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- import com.tgb.oa.PagerModel;
- import com.tgb.oa.manager.OrgManager;
- import com.tgb.oa.model.Orgnization;
- /**
- *
- * @ 实现组织机构管理接口
- * @author jnqqls
- * @group TGB
- * @version 1.0
- * @comments
- */
- public class OrgManagerImpl extends AbstractManager implements OrgManager {
- @Override
- public PagerModel findOrgs(int parentId) {
- //如果parentId=0,则查找顶级机构列表
- if(parentId == 0){
- return searchPaginated("from Orgnization o where o.parent is null");
- }
- return searchPaginated("from Orgnization o where o.parent.id = ?", parentId);
- }
- }
- </span>
剩下的就是相关的 Action进行调用,配置jsp页面.以上便是pager-taglib在项目中后台的相关使用.
总结:pager-taglib是分页的一个好工具,经过简单的配置可以轻松实现分页功能,我们所需要学习的是它本身所具有封装思想.