struts+spring+hibernate通用分页方法
分页有2种办法:
1、??? 从数据库中取得记录,在内存中再划分,如果遇到记录数很大的时候效率很成问题,此法不可取。
2、??? 采用hibernate的物理分页,每次只是取一页。从客户端传进来的是第几页和每页多少条记录,要首先查询符合记录的总记录数,再根据总记录数和当前页,每页记录数可以算出要取的是数据库中的第几条记录。2次查询不可避免了。
单元测试如下:
java 代码?
- public?final?void?testFindAllRole()?{??
- ??
- ????????????logger.debug("testFindAllRole");??
- ??
- ????????????long?l1=System.currentTimeMillis();??
- ??
- ????????????String?myaction="roleList.do";??
- ??
- ????????????String?curPageNO?=?"1";??
- ??
- ????????????CriteriaQuery?cq=new?CriteriaQuery(Role.class,curPageNO,myaction);??
- ??
- ????????????cq.setPageSize(10);??
- ??
- ????????????PageSupport?ps=BeanFactory.getInstance().getRightDelegate().findAllRole(cq,?state);??
- ??
- ????????????long?l2=System.currentTimeMillis();??
- ??
- ????????????AppUtils.printCollection(ps.getResultList());????
- ??
- ????????????System.out.println("一共用时为?:??"+(l2-l1));????????????
- ??
- ????????}??
CriteriaQuery类是对hibernate QBC查询方法的封装,需要的参数是当前操作的实体类,myaction,curPageNO,pageSize,以便构造出相应的上下翻页的工具条。
在delegate中只是将值向下传:
java 代码?
- public?PageSupport?findAllRole(CriteriaQuery?cq,?IState?state)?{??
- ??
- ????????if?(DelegateUtil.isNullParam(cq,?"CriteriaQuery",?state))?{??
- ??
- ????????????return?null;??
- ??
- ????????}??
- ??
- ????????Request?req?=?new?Request();??
- ??
- ????????req.setServiceName(ServiceConsts.FindAllRoleProcessor);??
- ??
- ????????req.setValue("CriteriaQuery",?cq);??
- ??
- ????????try?{??
- ??
- ????????????Response?resp?=?getDelegate().execute(req);??
- ??
- ????????????DelegateUtil.setIState(state,?resp);??
- ??
- ????????????return?(PageSupport)?(resp.getValue("PageSupport"));??
- ??
- ????????}?catch?(Exception?e)?{??
- ??
- ????????????DelegateUtil.handleException(e,?"findAllRole",?state);??
- ??
- ????????}??
- ??
- ????????return?new?PageSupport();??
- ??
- ????}?
在业务逻辑模块command中:java 代码?
- public?class?FindAllRole?extends?Command??
- {??
- ????private?RoleDao?dao;??
- ????public?void?setDao(RoleDao?dao)?{??
- ????????this.dao?=?dao;??
- ????}??
- ????public?void?execute(Map?params,?Map?response)?throws?Exception??
- ??
- ????{??
- ????????response.put("PageSupport",?(PageSupport)dao.find((CriteriaQuery)?params.get("CriteriaQuery"),true));??
- ????}??
- ……??
- ??
- }??
?? java 代码?
- public?PageSupport?find(final?CriteriaQuery?cq,final?boolean?isOffset)?{??
- ???????return?(PageSupport)getHibernateTemplate().execute(??
- ???????????????new?HibernateCallback()?{??
- ???????????????????public?Object?doInHibernate(Session?session)?throws?HibernateException,?SQLException?{??
- ???????????????????????Criteria?criteria?=?cq.getDetachedCriteria().getExecutableCriteria(session);???
- ???????????????????????//得到总行数??
- ???????????????????????int?allCounts?=?((Integer)?criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();???
- ???????????????????????criteria.setProjection(null);//还原????
- ???????????????????????int?curPageNO?=?PagerUtil.getCurPageNO(cq.getCurPage());//?当前页??
- ???????????????????????int?offset?=?PagerUtil.getOffset(allCounts,?curPageNO,?cq.getPageSize());??
- ???????????????????????String?toolBar?=?PagerUtil.getBar(cq.getMyaction(),allCounts,curPageNO,cq.getPageSize());??
- ??
- ???????????????????????if(isOffset){??
- ??
- ???????????????????????????criteria.setFirstResult(offset);??
- ??
- ???????????????????????????criteria.setMaxResults(cq.getPageSize());??
- ??
- ???????????????????????}??
- ???????????????????????return?new?PageSupport(criteria.list(),toolBar,offset,curPageNO);??
- ??
- ???????????????????????????}??
- ?????????????????????}??
- ??
- ???????????????,true);??
- ???}??
在后台的整个操作中非常简练,只需要将带上参数的CriteriaQuery传到dao就可以实现。CriteriaQuery封装了hibernate的DetachedCriteria。java 代码?
- public?class?CriteriaQuery?implements?Serializable{??
- ????public?CriteriaQuery(){??
- ????????super();??
- ????}??
- ????private?static?final?long?serialVersionUID?=?-1464383406564081554L;??
- ????//?初始化list??
- ????private?String?curPage=null?;??
- ????private?int?pageSize=10;??
- ????private?String?myaction;??
- ????private?String?myform;??
- ????private?CriterionList?criterionList;??
- ????private?DetachedCriteria?detachedCriteria;??
- ??
- ????public?CriteriaQuery(Class?c)?{??
- ????????this.criterionList?=?new?CriterionList();??
- ????????this.detachedCriteria=DetachedCriteria.forClass(c);??
- ????}??
- ????public?CriteriaQuery(Class?c,String?curPage,String?myaction,String?myform)?{??
- ????????this.myaction=myaction;??
- ????????this.myform=myform;??
- ????????this.curPage=curPage;??
- ????????this.criterionList?=?new?CriterionList();??
- ????????this.detachedCriteria=DetachedCriteria.forClass(c);??
- ????}??
- ????public?CriteriaQuery(Class?c,String?curPage,String?myaction)?{??
- ????????this.myaction=myaction;??
- ????????this.curPage=curPage;??
- ????????this.criterionList?=?new?CriterionList();??
- ????????this.detachedCriteria=DetachedCriteria.forClass(c);??
- ????}??
- ????public?CriterionList?getCriterionList()?{??
- ????????return?criterionList;??
- ????}??
- ????public?void?setCriterionList(CriterionList?criterionList)?{??
- ????????this.criterionList?=?criterionList;??
- ????}??
- ??
- ????public?String?getCurPage()?{??
- ????????return?curPage;??
- ????}??
- ????public?void?setCurPage(String?curPage)?{??
- ????????this.curPage?=?curPage;??
- ????}??
- ????public?DetachedCriteria?getDetachedCriteria()?{??
- ????????return?detachedCriteria;??
- ????}??
- ????public?void?setDetachedCriteria(DetachedCriteria?detachedCriteria)?{??
- ????????this.detachedCriteria?=?detachedCriteria;??
- ????}??
- ????public?void?add(Criterion?c)?{??
- ????????????detachedCriteria.add(c);??
- ????}??
- ????public?void?add()?{??
- ????????for(int?i=0;i
- ????????????add(getCriterionList().getParas(i));??
- ????????}??
- ????}??
- ????public?void?createAlias(String?name){??
- ????????detachedCriteria.createCriteria(name);??
- ????}??
- ????public?void?createAlias(String?name,String?value){??
- ????????detachedCriteria.createCriteria(name,value);??
- ????}??
- ????public?Criterion?and(CriteriaQuery?query,?int?source,?int?dest)?{??
- ????????return?Restrictions.and(query.getCriterionList().getParas(source),query.getCriterionList().getParas(dest));??
- ????}??
- ????public?Criterion?and(Criterion?c,CriteriaQuery?query,?int?source)?{??
- ????????return?Restrictions.and(c,?query.getCriterionList().getParas(source));??
- ????}??
- ????public?Criterion?and(Criterion?c1,?Criterion?c2)?{??
- ????????return?Restrictions.and(c1,c2);??
- ????}??
- ????public?Criterion?or(CriteriaQuery?query,?int?source,?int?dest)?{??
- ????????return?Restrictions.or(query.getCriterionList().getParas(source),query.getCriterionList().getParas(dest));??
- ????}??
- ??????
- ????public?Criterion?or(Criterion?c,CriteriaQuery?query,?int?source)?{??
- ????????return?Restrictions.or(c,?query.getCriterionList().getParas(source));??
- ????}??
- ??????
- ????public?void?or(Criterion?c1,?Criterion?c2)?{??
- ????????this.detachedCriteria.add(Restrictions.or(c1,c2));??
- ????}??
- ????public?void?addOrder(String?ordername,String?ordervalue)?{??
- ????????//?写入order查询条件??
- ????????if?("asc".equals(ordername))?{??
- ????????????detachedCriteria.addOrder(Order.asc(ordervalue));??
- ????????}?else?{??
- ????????????detachedCriteria.addOrder(Order.desc(ordervalue));??
- ????????}??
- ????}??
- ????public?void?eq(String?keyname,Object?keyvalue){??
- ????????criterionList.addPara(Restrictions.eq(keyname,?keyvalue));??
- ????}??
- ????public?void?notEq(String?keyname,Object?keyvalue){??
- ????????criterionList.addPara(Restrictions.or(Restrictions.gt(keyname,?keyvalue),Restrictions.lt(keyname,?keyvalue)));??
- ????}??
- ????public?void?like(String?keyname,Object?keyvalue){??
- ????????criterionList.addPara(Restrictions.like(keyname,?keyvalue));??
- ????}??
- ????public?void?gt(String?keyname,Object?keyvalue){??
- ????????criterionList.addPara(Restrictions.gt(keyname,?keyvalue));??
- ????}??
- ????public?void?lt(String?keyname,Object?keyvalue){??
- ????????criterionList.addPara(Restrictions.lt(keyname,?keyvalue));??
- ????}??
- ????public?void?le(String?keyname,Object?keyvalue){??
- ????????criterionList.addPara(Restrictions.le(keyname,?keyvalue));??
- ????}??
- ????public?void?ge(String?keyname,Object?keyvalue){??
- ????????criterionList.addPara(Restrictions.ge(keyname,?keyvalue));??
- ????}??
- ????public?void?ilike(String?keyname,Object[]?keyvalue){??
- ????????criterionList.addPara(Restrictions.in(keyname,?keyvalue));??
- ????}??
- ????public?void?between(String?keyname,Object?keyvalue1,Object?keyvalue2)?{??
- ????????Criterion?c=null;//?写入between查询条件??
- ????????if?(!AppUtils.isBlank(keyvalue1)?&&?!AppUtils.isBlank(keyvalue2))?{??
- ????????????c=Restrictions.between(keyname,?keyvalue1,?keyvalue2);??
- ????????}?else?if?(!AppUtils.isBlank(keyvalue1))?{??
- ????????????c=Restrictions.ge(keyname,?keyvalue1);??
- ????????}?else?if?(!AppUtils.isBlank(keyvalue2))?{??
- ????????????c=Restrictions.le(keyname,?keyvalue2);??
- ????????}??
- ????????criterionList.add(c);??
- ????}??
- ????public?int?getPageSize()?{??
- ????????return?pageSize;??
- ????}??
- ????public?void?setPageSize(int?pageSize)?{??
- ????????this.pageSize?=?pageSize;??
- ????}??
- ????public?String?getMyaction()?{??
- ????????return?myaction;??
- ????}??
- ????public?void?setMyaction(String?myaction)?{??
- ????????this.myaction?=?myaction;??
- ????}??
- ????public?String?getMyform()?{??
- ????????return?myform;??
- ????}??
- ????public?void?setMyform(String?myform)?{??
- ????????this.myform?=?myform;??
- ????}??
- }?
另外需要一些辅助类的支持:
例如PageSupport? 封装了返回的数据和工具条。
java 代码?
- public?class?PageSupport??implements?Serializable{??
- ????private?int?curPageNO;??
- ????private?int?offset;??
- ????private?String?toolBar;??
- ????private?List?resultList=null;??
- ??
- ????public?PageSupport()?{??
- ??
- ????}??
- ????public?PageSupport(List?resultList,String?toolBar,int?offset,int?curPageNO)?{??
- ????????this.curPageNO=curPageNO;??
- ????????this.offset=offset;??
- ????????this.toolBar=toolBar;??
- ????????this.resultList=resultList;??
- ????}??
- ????public?List?getResultList()?{??
- ????????return?resultList;??
- ????}??
- ??
- ????public?void?setResultList(List?resultList)?{??
- ????????this.resultList?=?resultList;??
- ????}??
- ??
- ????public?String?getToolBar()?{??
- ????????return?toolBar;??
- ????}?
java 代码?
CriterionList封装了Hibernate的参数:
- /**?
- ?*?封装了ArrayList,装的是Criterion?
- ?*/??
- public?class?CriterionList?extends?ArrayList?{??
- ????public?final?Criterion?getParas(final?int?index)?{??
- ????????return?(Criterion)?super.get(index);??
- ????}??
- ????public?final?void?addPara(final?int?index,?final?Criterion?p)?{??
- ????????super.add(index,?p);??
- ????}??
- ????public?final?void?addPara(final?Criterion?p)?{??
- ????????super.add(p);??
- ????}??
- ????public?final?int?indexofPara(final?Criterion?p)?{??
- ????????return?super.indexOf(p);??
- ????}??
- ????public?final?void?removePara(final?int?index)?{??
- ????????super.remove(index);??
- ????}??
- }??
PagerUtil用于将客户端的页码和每页多少个记录算出应该取数据库中的记录的位置,再由hibernate构造出一个三层的sql语句。
java 代码?
- public?class?PagerUtil?{??
- ????/**?
- ?????*??
- ?????*?@param?allCounts?总记录数?
- ?????*?@param?curPageNO??
- ?????*?@param?pageSize??每页显示的记录数目?
- ?????*?@return?
- ?????*/??
- ????public?static?String??getBar(String?action,String?form,int?allCounts,int?curPageNO,?int?pageSize){??
- ????????Pager?pager?=?null;??
- ????????????try?{??
- ????????????????if?(curPageNO<1)?curPageNO=1;??
- ????????????????if?(curPageNO>?(int)?Math.ceil((double)?allCounts?/?pageSize))???
- ????????????????????curPageNO?=(int)?Math.ceil((double)?allCounts?/?pageSize);??
- ????????????????//得到offset??
- ????????????????int?offset?=?(curPageNO-1)*pageSize;//从第几条开始取值??
- ?????????????????//生成工具条??
- ?????????????????pager=new?Pager(allCounts,offset,pageSize);??
- ?????????????????pager.setCurPageNO(curPageNO);//设置当前的页码??
- ????????????}?catch?(Exception?e)?{??
- ????????????????System.out.println("生成工具条出错!");??
- ??????????}??
- ?????????return?pager.getToolBar(action,form);??
- ????}??
- ??????
- ????public?static?String??getBar(String?url,int?allCounts,int?curPageNO,?int?pageSize){??
- ????????Pager?pager?=?null;??
- ????????????try?{??
- ????????????????if?(curPageNO<1)?curPageNO=1;??
- ????????????????if?(curPageNO>?(int)?Math.ceil((double)?allCounts?/?pageSize))???
- ????????????????????curPageNO?=(int)?Math.ceil((double)?allCounts?/?pageSize);??
- ????????????????//得到offset??
- ????????????????int?offset?=?(curPageNO-1)*pageSize;//从第几条开始取值??
- ?????????????????//生成工具条??
- ?????????????????pager=new?Pager(allCounts,offset,pageSize);??
- ?????????????????pager.setCurPageNO(curPageNO);//设置当前的页码??
- ????????????}?catch?(Exception?e)?{??
- ????????????????System.out.println("生成工具条出错!");??
- ??????????}??
- ?????????return?pager.getToolBar(url);??
- ????}??
- ??????
- ????public?static?int?getOffset(int?rowCounts,int?curPageNO,?int?pageSize){??
- ????????int?offset=0;??
- ????????????try?{??
- ????????????????//得到第几页??
- ????????????????if?(curPageNO<1)?curPageNO=1;??
- ????????????????if?(curPageNO>?(int)?Math.ceil((double)?rowCounts?/?pageSize))???
- ????????????????????curPageNO?=(int)?Math.ceil((double)?rowCounts?/?pageSize);??
- ????????????????//得到offset??
- ??????????????????offset?=?(curPageNO-1)*pageSize;??
- ????????????}?catch?(Exception?e)?{??
- ????????????????System.out.println("getOffset出错!");??
- ????????????}????
- ???????return?offset;??
- ????}??
- ??????
- ????public?static?int?getCurPageNO(String?curPage){??
- ????????????int?curPageNO;??
- ?????????????if?(curPage==null||"".equals(curPage.trim()))?{??
- ?????????????????curPageNO=1;//第一次处于第一页??
- ??????????????}?else?{??
- ??????????????????try?{??
- ??????????????????????curPageNO?=?Integer.parseInt(curPage);//得到当前页??
- ????????????????}?catch?(Exception?e)?{??
- ????????????????????curPageNO=1;??
- ????????????????}??
- ??????????????}??
- ?????????????return?curPageNO;??
- ????????}??
- }?
- 未完,待续
即页面A上同时包含 B,B,B,B,B 5个相同的模块,5个B的内容完全相同,但要保证每个B模块的分页完全独立。 4 楼 onecan 2007-06-23 每个工具条是跟返回的记录绑定到一个pagesupport类里面,通过辅助的类将客户端传进来的参数转换为数据库记录的位置,并且用这些参数来构造一个工具条。pagesupport里面就一个list和string类型的变量,list是返回的记录,string是工具条的html代码,2者是对应的。不同的分页对应到不同的记录和工具条。但是5个分页同时放在一个页面,要注意不要同时刷新了。 5 楼 rainytooo 2007-06-25 现在大家都有自己的分页方案了吧
6 楼 yongyuan.jiang 2007-06-25 简单的分页写了那么多行代码,看都没心情看。