`
a137268431
  • 浏览: 145599 次
文章分类
社区版块
存档分类
最新评论

Springmvc 应用Mongodb分页实现

 
阅读更多

对于web应用来说分页显示数据是是最基本的功能,作为经常开发web应用的程序员来说这个功能也小菜一碟,但是对于初学者来说却是是个常见的问题,以前自学web开发的时候对这个问题也是各种google,整了半天才实现。

现在手中的项目正好也需要一个分页的功能,这个项目用了spring mvc数据库用到了mongodb,自己就写了一个分页的标签供整个项目来使用,今天周六加完班闲着没事就把分页的实现写出来以便大家参考,不当之处欢迎批评指正。

1)分页:

一般都是把一次查询分几次查询来显示。用户每次点击页数(或者上一页下一页)的时候实际上一次查询请求。查询设定数据的条数返回并显示。

2) mongodb分页用到的工具

在查询的时候需要用到Query来保存用户的查询条件,该类有两个方法是实现分页功能的核心一个是skip(int),一个是limit(int)方法,其中limit用来限制每次查询的条数,也是每显示的条数。而skip是跳过当前页之前的所有页面的数据条数开始查询

3)分页关键点(所需的数据):

i) 每页显示的条数pageSize

ii) 当前的页数currentPage,而前面的skip方法传入的参数就是根据currentPage和pageSize来决定的,skip = (currentPage-1)*pageSize

4)分页的具体实现

通过上面的分析,分页简单来说就是用户点击分页的时候提交一个关键数据(currentPage)到后台,后台根据currentPage来进行分页查询;至于上面的pageSize,

在后台设置一个变量来控制即可。

下面是项目中的用来查询的基类:MongodbBaseDao<T>的部分代码

  1. //每页显示五条
  2. protectedstaticfinalintPAGE_SIZE=8;
  3. /**
  4. *通过条件查询,查询分页结果
  5. */
  6. publicPagination<T>getPage(intcurrentPage,Queryquery){
  7. //获取总条数
  8. longtotalCount=this.mongoTemplate.count(query,this.getEntityClass());
  9. //总页数
  10. inttotalPage=(int)(totalCount/PAGE_SIZE);
  11. intskip=(currentPage-1)*PAGE_SIZE;
  12. Pagination<T>page=newPagination<T>(currentPage,totalPage,(int)totalCount);
  13. query.skip(skip);//skip相当于从那条记录开始
  14. query.limit(PAGE_SIZE);//从skip开始,取多少条记录
  15. List<T>datas=this.find(query);
  16. page.build(datas);//获取数据
  17. returnpage;
  18. }

上面的代码中Pagination类保存了分页所需的必要的数据,比如当前页currentPage,总页数totalPage,总条数totalCount,当然还有数据集合List 用来保存页面所需的数据。另外getEntityClass()是T所对应的class对象(由子类来具体实现)。例如项目中有一个子类VideoMongodbDao

  1. @Service
  2. publicclassVideoMongodbDaoextendsMongodbBaseDao<Video>{
  3. @Override
  4. protectedClass<Video>getEntityClass(){
  5. returnVideo.class;
  6. }
  7. }

分页数据封装类Pagination<T>,里面提供了分页的数据

  1. publicclassPagination<T>{
  2. /**列表每页显示条数*/
  3. privateIntegerpageSize=8;
  4. /**列表当前页*/
  5. privateIntegercurrentPage=1;
  6. /**列表总页数*/
  7. privateIntegertotalPage=1;
  8. /**列表总数据量*/
  9. privateIntegertotalNumber=0;
  10. /**数据集*/
  11. privateListitems;
  12. publicIntegergetPageSize(){
  13. returnpageSize;
  14. }

Pagination类还有一个重要的build方法,根据该类封装的数据来设定分了多少页,具体实现方法如下

  1. /**
  2. *处理查询后的结果数据
  3. *
  4. *@paramitems
  5. *查询结果集
  6. *@paramcount
  7. *总数
  8. */
  9. publicvoidbuild(Listitems){
  10. this.setItems(items);
  11. intcount=this.getTotalNumber();
  12. intdivisor=count/this.getPageSize();
  13. intremainder=count%this.getPageSize();
  14. this.setTotalPage(remainder==0?divisor==0?1:divisor:divisor+1);
  15. }

所以在对应的controller对应的方法中查询的时候,可以这么处理

  1. Queryquery=newQuery();
  2. CriteriachannleIdCri=Criteria.where("channelId").is(channel_id);
  3. query.addCriteria(channleIdCri);
  4. //获取当前页
  5. StringcurrentPageStr=request.getParameter("currentPage");
  6. intcurrentPage=0;
  7. if(currentPageStr!=null){
  8. currentPage=Integer.valueOf(currentPageStr);
  9. }
  10. Pagination<Video>videos=dao.getPage(currentPage,query);
  11. m.addAttribute("videos",videos);//from

下面需要生成分页当行条,在这里用到了spring的标签来处理,对应的是标签类PaginationTag,该类封装了页面表单form对应的id,分页显示所需的数据,以及分页显示可点击的页面的长度。该类如下

  1. publicclassPaginationTagextendsTagSupport{
  2. /**列表页面的form标签id值*/
  3. privateStringform;
  4. /**与后台交互,保存在request中的数据,该数据包含l*/
  5. privateStringpageInfo;//request对应的bean包含了分页的一些数据
  6. /**分页显示可点击页数的长度*/
  7. privateintsize;
  8. publicPaginationTag(){
  9. this.form="form";
  10. this.size=5;
  11. }

生成的分页导航条的代码如下

  1. @Override
  2. publicintdoStartTag()throwsJspException{
  3. inthalf=size/2;
  4. intpoint=size/2+size%2;
  5. intstart=1;
  6. intloop=size;
  7. Paginationquery=(Pagination)this.pageContext.getRequest().getAttribute(pageInfo);
  8. intpageSize=query.getPageSize();
  9. intcurrentPage=query.getCurrentPage();
  10. inttotalPage=query.getTotalPage();
  11. longtotalNumber=query.getTotalNumber();
  12. if(totalPage<=size){
  13. start=1;
  14. loop=totalPage;
  15. }else{
  16. if(currentPage>point&&currentPage<totalPage-half+1){
  17. start=1+(currentPage-point);
  18. }elseif(currentPage>totalPage-half){
  19. start=totalPage-size+1;
  20. }
  21. }
  22. if(currentPage<=0){
  23. currentPage=1;
  24. }
  25. StringBuildersb=newStringBuilder();
  26. sb.append("<divclass=\"box-ttl\"><divclass=\"g4\">共<spanclass=\"text-info\">");
  27. sb.append(totalNumber).append("</span>条数据");
  28. sb.append("/共<spanclass=\"text-info\">");
  29. if(totalNumber!=0){
  30. sb.append(totalPage).append("</span>页!</div><divclass=\"boxcollapsedg6flt-r\"><ulclass=\"nav-menu\">");
  31. }else{
  32. sb.append(0).append("</span>页!</div><divclass=\"boxcollapsedg6flt-r\"><ulclass=\"nav-menu\">");
  33. }
  34. //处理上一页
  35. if(currentPage==1){
  36. sb.append("<liclass=\"disabled\"><ahref=\"#\">上一页</a></li>");
  37. }else{
  38. sb.append("<li><ahref=\"javascript:dopage("+(currentPage-1)+",'"+form+"');\">上一页</a></li>");
  39. }
  40. //处理中间数据
  41. for(inti=start;i<start+loop;i++){
  42. //<liclass="active"><ahref="#">1</a></li>
  43. if(currentPage==i){
  44. sb.append("<liclass=\"active\"><ahref=\"#\">"+i+"</a></li>");
  45. }else{
  46. //<li><ahref="#">2</a></li>
  47. sb.append("<li><ahref=\"javascript:dopage("+i+",'"+form+"');\">"+i+"</a></li>");
  48. }
  49. }
  50. //处理下一页
  51. if(currentPage==totalPage){
  52. sb.append("<liclass=\"disabled\"><ahref=\"#\">下一页</a></li>");
  53. }else{
  54. sb.append("<li><ahref=\"javascript:dopage("+(currentPage+1)+",'"+form+"');\">下一页</a></li>");
  55. }
  56. sb.append("</ul></div></div>");
  57. sb.append("<inputtype=\"hidden\"id=\"currentPage\"name=\"currentPage\"value=\""+currentPage+"\"/>");
  58. try{
  59. pageContext.getOut().write(sb.toString());
  60. }catch(IOExceptione){
  61. thrownewJspException(e.toString(),e);
  62. }
  63. returnsuper.doStartTag();
  64. }

有上面的标签可以发现,每次点击页面页数的时候是用过js的dopage方法来实现的,该js方法根据form.submit()来提交信息查询信息(特别是currentPage数据)

js的代码如下

[javascript]view plaincopy在CODE上查看代码片派生到我的代码片
  1. functiondopage(currentPage,formid){
  2. $("#currentPage").val(currentPage);
  3. $("#"+formid).submit();
  4. }

在jsp页面中只需要添加上述标签即可(标签类Pagination以及转换成tld文件了—)

  1. <div>
  2. <tv:paginationpageInfo="videos"form="video-form"size="5"></tv:pagination>
  3. </div>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics