java分页的实现,插件PageHelper的使用及原理
2017-04-08 15:49
886 查看
如果你只希望知道PageHelper的用法,直接去github查看官网文档 Mybatis-PageHelper.
1.关于分页。
在web项目中,分页是一个常见的功能。在我刚学完javaweb的时候在没有用任何框架的情况下做过分页,代码非常的冗余、难看,后台每个POJO类的增删改查里都需要写:(pageSize为每页大小,pageNum为查询的页数)
而前端也要写多个jsp,一个分页就对应了一个jsp。导致不管是前后台,代码都大量重复,实在是太不优雅了。
2.PageHelper的优缺点。
PageHelper做的是什么呢?它封装了分页的后台部分,说得更简单点,就是你不需要每个POJO类的增删改查里都包括那两个方法了,它帮你做了。你只需要有一个selectAll的方法,它会根据你使用的数据库来将你selectAll的sql改装成一个分页查询的sql,并顺带生成一个查询总数的sql。
如图,对应不同的数据库有不同的方言,如常见的Mysql,分页关键字是limit,它就是这样组装你的sql。
PageHelper不仅帮你分页查询了数据,在返回时直接返回Page对象,里更是封装了许多分页信息。但是在前后台json数据交互时,由于Page对象继承自ArrayList,json不会保留其分页信息,所以在使用时往往是这样使用的:
即将查询出来的Page转为PageInfo(没有继承ArrayList),将你的PageInfo<Object>返回给前台就可以了。
至此,我们可以看到PageHelper的优缺点。
优点:封装分页sql,使我们不需要每个地方都去写分页的查询语句;同时,使我们select的sql语句向下兼容,换了数据库也不需要更改sql代码;
缺点:自带的Page对象转json时会丢失分页数据;而转为PageInfo对象时分页信息过多(这一点作者已在github上说明,建议自己实现PageInfo)
3.前端的实现。
在拿到后台传来的数据后,前端要做的要不少。考虑一个这样的分页:
<< < 1 2 3 4 5 > >> 难点在中间的五个数字,通常情况下PageNum(当前你浏览的页数)在中间,每当翻页时五个数字都会发生变化,但如果总页数较小或者PageNum较小时则不一定发生变动,同时还需要注意总页数小于5的问题。
<< 为到第一页
< 为上一页
firstNum 通常为PageNum - 2
secondNum 通常为PageNum - 1
thirdNum 通常为PageNum
fourthNum 通常为PageNum + 1
fifthNum 通常为PageNum + 2
> 为下一页
>>为最后一页
直接看代码:
4.综合解决方案。
后台:采用PageHelper查询出来的Page转为PageInfo,如果需求的查询功能比较简单或者对性能要求高,自己照着PageInfo实现一个MyPageInfo,其中只要自己需要的属性、方法即可。
前端:写一个page.js提供一个getPageArr的方法,对传来的做PageNum做处理,返回一个数组,即firstNum至fifthNum,当然,要注意数据库不到5页的返回哦。
1.关于分页。
在web项目中,分页是一个常见的功能。在我刚学完javaweb的时候在没有用任何框架的情况下做过分页,代码非常的冗余、难看,后台每个POJO类的增删改查里都需要写:(pageSize为每页大小,pageNum为查询的页数)
getList(int pageSize,int pageNum); getTotal();
而前端也要写多个jsp,一个分页就对应了一个jsp。导致不管是前后台,代码都大量重复,实在是太不优雅了。
2.PageHelper的优缺点。
PageHelper做的是什么呢?它封装了分页的后台部分,说得更简单点,就是你不需要每个POJO类的增删改查里都包括那两个方法了,它帮你做了。你只需要有一个selectAll的方法,它会根据你使用的数据库来将你selectAll的sql改装成一个分页查询的sql,并顺带生成一个查询总数的sql。
如图,对应不同的数据库有不同的方言,如常见的Mysql,分页关键字是limit,它就是这样组装你的sql。
@Override public String getPageSql(String sql, Page page, CacheKey pageKey) { StringBuilder sqlBuilder = new StringBuilder(sql.length() + 14); sqlBuilder.append(sql); if (page.getStartRow() == 0) { sqlBuilder.append(" LIMIT "); sqlBuilder.append(page.getPageSize()); } else { sqlBuilder.append(" LIMIT "); sqlBuilder.append(page.getStartRow()); sqlBuilder.append(","); sqlBuilder.append(page.getPageSize()); pageKey.update(page.getStartRow()); } pageKey.update(page.getPageSize()); return sqlBuilder.toString(); }
PageHelper不仅帮你分页查询了数据,在返回时直接返回Page对象,里更是封装了许多分页信息。但是在前后台json数据交互时,由于Page对象继承自ArrayList,json不会保留其分页信息,所以在使用时往往是这样使用的:
@Override public PageInfo<TopicPost> selectAllPublicTopicPost(int pageNum) { int pageSize = 10; PageInfo<TopicPost> topicPostList = new PageInfo<TopicPost>();//主题帖表 try { PageHelper.startPage(pageNum, pageSize); topicPostList = ((Page<TopicPost>)topicPostDao.daoSelectAllPublicTopicPost()).toPageInfo(); } catch (Exception e) { log.error("查询状态正常的主题帖失败!"+e.toString()); e.printStackTrace(); } return topicPostList; }
即将查询出来的Page转为PageInfo(没有继承ArrayList),将你的PageInfo<Object>返回给前台就可以了。
至此,我们可以看到PageHelper的优缺点。
优点:封装分页sql,使我们不需要每个地方都去写分页的查询语句;同时,使我们select的sql语句向下兼容,换了数据库也不需要更改sql代码;
缺点:自带的Page对象转json时会丢失分页数据;而转为PageInfo对象时分页信息过多(这一点作者已在github上说明,建议自己实现PageInfo)
3.前端的实现。
在拿到后台传来的数据后,前端要做的要不少。考虑一个这样的分页:
<< < 1 2 3 4 5 > >> 难点在中间的五个数字,通常情况下PageNum(当前你浏览的页数)在中间,每当翻页时五个数字都会发生变化,但如果总页数较小或者PageNum较小时则不一定发生变动,同时还需要注意总页数小于5的问题。
<< 为到第一页
< 为上一页
firstNum 通常为PageNum - 2
secondNum 通常为PageNum - 1
thirdNum 通常为PageNum
fourthNum 通常为PageNum + 1
fifthNum 通常为PageNum + 2
> 为下一页
>>为最后一页
直接看代码:
//查看所有状态正常的主题帖 function selectAllPublicTopicPost(pageNum){ var url = "/guestbook/rs/topicpost/selectallpublictopicpost"; var json = JSON.stringify(pageNum); $.ajax({ url:url, type:'POST', async:true, data: json, contentType:"application/json", dataType:'json', success:function(data,textStatus,jqXHR){ var firstNum = pageNum - 2; var secondNum = pageNum -1; var thirdNum = pageNum; var fourthNum = pageNum + 1; var fifthNum = pageNum + 2; var prePage = pageNum - 1; var nextPage = pageNum + 1; if(pageNum < 4 || data.pages < 6){ firstNum = 1; secondNum = 2; thirdNum = 3; fourthNum = 4; fifthNum = 5; } else if(pageNum > data.pages-2){ firstNum = data.pages-4; secondNum = data.pages-3; thirdNum = data.pages-2; fourthNum = data.pages-1; fifthNum = data.pages; } if(data.isFirstPage){ prePage = 1; } if(data.isLastPage ){ nextPage = data.pages; } var index_page = "<li><a onclick='selectAllPublicTopicPost(1)' aria-label='Previous'><span aria-hidden='true'><<</span></a></li>" +"<li><a onclick='selectAllPublicTopicPost("+prePage+")' aria-label='Previous'><span aria-hidden='true'><</span></a></li>" +"<li><a onclick='selectAllPublicTopicPost("+firstNum+")'>"+firstNum+"</a></li>"; if(secondNum <= data.pages){ index_page = index_page + "<li><a onclick='selectAllPublicTopicPost("+secondNum+")'>"+secondNum+"</a></li>"; } if(thirdNum <= data.pages){ index_page = index_page + "<li><a onclick='selectAllPublicTopicPost("+thirdNum+")'>"+thirdNum+"</a></li>"; } if(fourthNum <= data.pages){ index_page = index_page + "<li><a onclick='selectAllPublicTopicPost("+fourthNum+")'>"+fourthNum+"</a></li>"; } if(fifthNum <= data.pages){ index_page = index_page + "<li><a onclick='selectAllPublicTopicPost("+fifthNum+")'>"+fifthNum+"</a></li>"; } index_page = index_page +"<li><a onclick='selectAllPublicTopicPost("+nextPage+")' aria-label='Next'><span aria-hidden='true'>></span></a></li>" +"<li><a onclick='selectAllPublicTopicPost("+data.pages+")' aria-label='Next'><span aria-hidden='true'>>></span></a></li>"; $("#index_page").html(index_page); //以下内容不重要 var tp = ""; jQuery.each( data.list,function(i,item){ tp = tp + "<div class='col-lg-4'><a href='/guestbook/contents.html?topicPostId=" +item.id +"' target='_blank'>" +item.title +"</a></div><div class='col-lg-2'>" +item.keyword +"</div><div class='col-lg-2'>" +vagueTime(new Date(item.time).toLocaleString()) +"</div><div class='col-lg-2'><a href='/guestbook/cust_info.html?uid=" +item.userId +"' target='_blank'>" +item.userName +"</a></div><div class='col-lg-1'>" +item.replyNumber +"<br/><br/></div>"; }); $("#topic_list").html(tp); } }) }这样就是一个完整的分页的前后台实现,但前端依然是每一个分页都要去写这么一大段代码,还有改善空间。
4.综合解决方案。
后台:采用PageHelper查询出来的Page转为PageInfo,如果需求的查询功能比较简单或者对性能要求高,自己照着PageInfo实现一个MyPageInfo,其中只要自己需要的属性、方法即可。
前端:写一个page.js提供一个getPageArr的方法,对传来的做PageNum做处理,返回一个数组,即firstNum至fifthNum,当然,要注意数据库不到5页的返回哦。
相关文章推荐
- pageHelper分页插件实现原理及使用方法
- mybatis-PageHelper分页插件的原理和使用
- MyBatis中如何使用PageHelper插件实现 分页
- [Extjs] Ext4 Ext.grid.Panel 分页实现(mybatis 分页插件-PageHelper 使用)
- PageHelper分页插件使用
- 分页插件pageHelper工作中的简单使用
- 基于ssm框架的mybatis pagehelper分页插件的使用
- 基于spring boot的mysql使用pagehelper实现分页功能
- 使用ajax、pageHelpler分页插件、利用json数据特性实现分页查询
- Mybatis分页插件-PageHelper的使用
- mybatis框架---分页插件PageHelper的使用方法
- mybatis分页插件PageHelper的使用
- Spring + Mybatis 使用 PageHelper 插件分页
- mybatis分页插件pageHelper的使用
- Spring + Mybatis 使用 PageHelper 插件分页
- mybatis实现分页插件PageHelper
- mybatis 分页插件pagehelper集成及使用
- Mybatis阿里云分页插件-PageHelper使用
- mybatis系列五:使用pagehelper5插件进行分页
- (转)淘淘商城系列——MyBatis分页插件(PageHelper)的使用以及商品列表展示