@RequestMapping(value = "/findAll",method = RequestMethod.GET)
public String getUsers(){
int pageNum = 1;
int pageSize = 10;
PageHelper.startPage(pageNum, pageSize);
List<User> list = userService.findAllUser();
PageInfo pageInfo = new PageInfo(list);
Page page = (Page) list;
return "PageInfo: " + JSON.toJSONString(pageInfo) + ", Page: " + JSON.toJSONString(page);
}
<select id="findAllUser" resultType="User">
SELECT * from users
</select>
PageInfo: {"endRow":10,"firstPage":1,"hasNextPage":true,"hasPreviousPage":false,"isFirstPage":true,"isLastPage":false,"lastPage":2,"list":[{"id":2,"name":"awbeci"},{"id":3,"name":"wulingmei"},{"id":4,"name":"qinxin"},{"id":5,"name":"qinxin2"},{"id":6,"name":"qinxin3"},{"id":7,"name":"???"},{"id":8,"name":"caochenglu"},{"id":10,"name":"sdfsdfs"},{"id":13,"name":"wangle"},{"id":14,"name":"react-cd-player"}],"navigateFirstPage":1,"navigateLastPage":2,"navigatePages":8,"navigatepageNums":[1,2],"nextPage":2,"pageNum":1,"pageSize":10,"pages":2,"prePage":0,"size":10,"startRow":1,"total":17}, Page: [{"id":2,"name":"awbeci"},{"id":3,"name":"wulingmei"},{"id":4,"name":"qinxin"},{"id":5,"name":"qinxin2"},{"id":6,"name":"qinxin3"},{"id":7,"name":"???"},{"id":8,"name":"caochenglu"},{"id":10,"name":"sdfsdfs"},{"id":13,"name":"wangle"},{"id":14,"name":"react-cd-player"}]
根据上面代码,确实可以分页了,但是我有点想不通:因为我的查询语句是select * from users,难道是我先从数据库中查询出所有数据,然后再在getUsers方法里面通过查询插件再进行分页???
你代码使用了mybatis page helper插件,他本身是一个物理分页插件,实际原理就是修改最后的执行sql,增加xi相应的分页内容,是基于拦截器实现的。
例如,首先你配置了PageHelper的page number和size,调用完startPage后,他会通过PageInterceptor对其后的第一个执行sql进行拦截,也就是对List<User> list = userService.findAllUser()进行拦截,这里原本的sql可能是 select * from users,他会自动拼接上分页的sql语句,比如mysql环境的话,就是拼接上limit语句,随后执行,最后的结果,可以通过PageInfo和Page进行获取。
更详细的使用方法,你可以看他的文档 https://pagehelper.github.io/...,本身原理比较简单,你可以通过输出log或者debug步进的形式,来看一下最后执行的sql,实际也可以通过自己写个拦截器,做到同样的效果。
补充一下:mybatis原生也是支持分页的,但为了与数据库语法解耦,实现的是逻辑分页,首先将所有结果查询出来,然后通过计算offset和limit,只返回部分结果,操作在内存中进行,所以也叫内存分页,当数据量比较大的时候,肯定是不行的,核心类叫rowbounds,有兴趣可以搜一下。