龙空技术网

再议分页插件PageHelper

软件老王 163

前言:

而今同学们对“分页插件pagehelper原理”大约比较讲究,咱们都想要知道一些“分页插件pagehelper原理”的相关知识。那么小编也在网络上网罗了一些关于“分页插件pagehelper原理””的相关知识,希望我们能喜欢,同学们一起来学习一下吧!

1、问题描述

java分页以前介绍过pagehelper,最近项目中又用到分页,看了下,发现使用springboot下使用起来更加方便了,又系统看了看,分享下,希望能帮到有需要的朋友。

2、解决方案2.1 官方文档

还是那句话,官方文档才是yyds,地址:

第一个mybatis-pagehelper是源码实现,第二个springboot的是对第一个做了封装。

目前springboot下最新的pagehelper版本是:1.3.1

2.2 具体配置与使用

因为老王的代码是公司电脑上,复制不出来,本地简单弄了个案例说明下。

springboot下使用pagehelper更加方便了,只需要配置两个地方就可以了

2.2.1 pom文件

        <dependency>            <groupId>com.github.pagehelper</groupId>            <artifactId>pagehelper-spring-boot-starter</artifactId>            <version>1.3.1</version>        </dependency>

有了springboot下的pagehelper的gav,就不需要mybatis的gav了,pagehelper的gav中已经包含mybatis的gav了。

2.2.2 yml文件配置下

pagehelper:  helper-dialect: mysql  reasonable: true  support-methods-arguments: true  params: count=countSql

主要是配置下helper-dialect,这里是根据不同的配置,会使用不同的方言。

2.2.3 代码中运用

        Page<TLaowang> page = PageHelper.startPage(info.getPageNum(), info.getPageSize());        List<TLaowang> list = tLaowangMapper.selectAll();

通过在待执行的mybatis的mppper前设置page,就可以达到分页的目的了。

2.2.4 重要提示

这里提到官网有个重要提示:

PageHelper.startPage方法重要提示只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询(Select)方法会被分页。请不要配置多个分页插件请不要在系统中配置多个分页插件(使用Spring时,mybatis-config.xml和Spring<bean>配置方式,请选择其中一种,不要同时配置多个分页插件)!分页插件不支持带有for update语句的分页对于带有for update的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。分页插件不支持嵌套结果映射由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。

很重要的一点PageHelper.startPage要紧挨mybatis执行方法,网上查的原因,不保证真的准确。

 PageHelper方法使用了静态的ThreadLocal参数,分页参数和线程是绑定的。内部流程是ThreadLocal中设置了分页参数(pageIndex,pageSize),之后在查询执行的时候,获取当线程中的分页参数,执行查询的时候通过拦截器在sql语句中添加分页参数,之后实现分页查询,查询结束后在 finally 语句中清除ThreadLocal中的查询参数

源码:

3、代码验证3.1 分层代码

(1)cotroller

    @RequestMapping(value ="/selectAll", method = RequestMethod.POST)    public  Object select(LPageInfo info) {        return testService.selectAll(info);    }

(2)service

    public  List<TLaowang> selectAll(LPageInfo info) {        Page<TLaowang> page = PageHelper.startPage(info.getPageNum(), info.getPageSize());        List<TLaowang> list = tLaowangMapper.selectAll();//        PageInfo pageInfo = new PageInfo(list);//        System.out.println(pageInfo.getTotal());        System.out.println(page.getTotal());        return list;    }

简要说明

这里两个说明,一是tLaowangMapper要紧跟PageHelper;二是total页码,可以通过page获取,也可以通过PageInfo获取,另外会出现跨service获取total页码丢失的情况,要特别注意位置问题。

(3)mapper

  <select id="selectAll" resultMap="BaseResultMap">    select    <include refid="Base_Column_List" />    from t_laowang  </select>

(4)测试数据

3.2 执行效果3.2.1 swagger执行

pagenum=3,pagesize=3

3.2.2 debug看效果

从debug效果看,list已经是page类型了,返回3条数据,数据是从第7条到第9条,total是9条。

3.2.3 通过idea插件mybatis-log查看数据库执行sql

说明:

(1)从图中不难看出,pagehelper执行了两条sql,一条获取total总数,二是调用mysql的分页语句进行分页。

mysql分页语句:

select * from table limit (start-1)*pageSize,pageSize; 其中start是页码,pageSize是每页显示的条数。查询第1条到第10条的数据的sql是:select * from table limit 0,10;  ->对应我们的需求就是查询第一页的数据:select * from table limit (1-1)*10,10;例如:select * from table limit 0,10;  --从第0条开始,查询10条数据。     select * from table limit 10,10;  --从第10条开始,查询10条数据。

(2)分页pagenum是从1开始的。

4、总结

简单来说,pagehelper是通过封装拦截,将分页拼接到待执行sql中,起到分页的效果,底层还是使用的对应数据的分页语句,因为不同的数据库分页语句不一样,所以才需要配置数据库类型,拼接不同的分页语句到待执行sql中去。

更多信息请关注@软件老王,关注不迷路,软件老王和他的IT朋友们,分享一些他们的技术见解和生活故事。

标签: #分页插件pagehelper原理