准备系列-Mybatis(十二) TKmybatis GitHub插件PageHelper实现分页

900 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 12 天,点击查看活动详情

前几篇我们介绍了4种Mybatis的分页方法, 今天我们介绍第五种,使用分页插件来实现分页逻辑

1.Springboot 集成PageHelper Starter

在Pom文件中加 pagehelper-spring-boot-starter 依赖 注意这个版本可能会有问题一定要选自己适合的版本

  • 我的springboot是2.7.8
  • 然后最早用的 1.2.10 会出现报错 Requested bean is currently in creation

解决办法:使用pagehelper的1.4.1之后的版本即可

  • 后来替换成 1.4.1的版本才可以, 因为spring-boot2.5之后的版本解决了循环依赖的问题,相应的依赖插件必须更新到最新不存在循环依赖的代码版本,否则启动springboot就会报错。
Error creating bean with name 'com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'com.github.pagehelper
Requested bean is currently in creation: Is there an unresolvable circular reference?

pagehelper-spring-boot-starter 依赖及版本

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

2.配置PageHelper分页信息

application.properties 种配置分页信息

#追加 page helper配置信息
#数据库类型
pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql
pagehelper.page-size-zero=true

参数说明如下

  • pagehelper.helper-dialect
    • 标识是哪一种数据库数据库配置 可以是mysql 或者 Oracle, Mysql, MariaDB, SQLite, Hsqldb, PostgreSQL 六种数据库
  • pagehelper.reasonable=true 分页合理化参数
    • 默认值为false。
    • 配置了分页合理化参数为 true 后,当查询页码超出总页数,拦截器是如何实现仍然返回最后一页的数据,for循环是尤为注意,容易导致死循环,超出页数也不会返回空,会返回最后一页数据
  • pagehelper.support-methods-arguments
    • 默认值false
    • 配置true 分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页
  • pagehelper.params
    • 为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值
    • 默认值为pageNum=pageNum; pageSize=pageSize; count=countSql; reasonable=reasonable; pageSizeZero=pageSizeZero
  • pagehelper.page-size
    • 如果 pageSize=0 就会查询出全部的结果, 等于 没有执行分页查询

3.代码逻辑实现

3.1 业务逻辑实现

TestController

@RequestMapping("/temp/query10")
@ResponseBody
public void query10(Integer pageNumber) {
    //pageNumber 默认都是 从第1页开始,每页取3个
    Page page = new Page(pageNumber , 3);

    PageInfo<UserInfoPO> pluginsPage = pageService.pluginsPage(page);
    log.info(" pluginsPage 第{}页 数据 \r\n:{} ", page.getPageNumber(), printUser(pluginsPage.getList()));
}

Service业务类信息

/**
 *  插件分页
 */
PageInfo<UserInfoPO> pluginsPage(Page page);
===========================================

@Override
public PageInfo<UserInfoPO> pluginsPage(Page page) {
    //设置分页配置信息
    PageHelper.startPage(page.getPageNumber(), page.getPageSize());

    Example example = new Example(UserInfoPO.class);
    List<UserInfoPO> userInfoPOS = mapper.selectByExample(example);

    return new PageInfo<>(userInfoPOS);
}

执行 curl 127.0.0.1:8800/temp/query10?pageNumber=3

查询结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3d1fe006] was not registered for synchronization because synchronization is not active
2023-02-12 00:34:01.657  INFO 8496 --- [nio-8800-exec-1] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@7fcaf714] will not be managed by Spring
==>  Preparing: SELECT count(0) FROM user_info 
==> Parameters: 
<==    Columns: count(0)
<==        Row: 14
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3d1fe006]
2023-02-12 00:34:01.691  INFO 8496 --- [nio-8800-exec-1] c.j.tdmybatis.controller.TestController  :  pluginsPage 第3页 数据 
:UserInfoPO{id=7, userId='77', userName='gg', age=41, address='郑州'}
UserInfoPO{id=8, userId='88', userName='hh', age=4, address='武汉'}
UserInfoPO{id=9, userId='99', userName='ii', age=14, address='武汉'}

查询结果正确 也是 7,8,9 三条数据

image.png

3.2 加查询条件的 分页逻辑

如果我有一些查询条件呢? 比如年龄 > 10 岁的 按照年龄 升序 排列, 看看分页是否能满足

SELECT * FROM `user_info` where age > 20 order by age asc;
  • 第 1 页 4,9,12 记录
  • 第 2 页 13,5,10 记录
  • 第 3 页 3,6,14 记录
  • 第 4 页 7,11 记录 image.png

TestController

@RequestMapping("/temp/query11")
@ResponseBody
public void query11(Integer pageNumber) {
    //pageNumber 默认都是 从第1页开始,每页取3个
    Page page = new Page(pageNumber, 3);

    PageInfo<UserInfoPO> pluginsPageWithCondition = pageService.pluginsPageWithCondition(page);
    log.info(" pluginsPageWithCondition 第{}页 数据 \r\n:{} ", page.getPageNumber(), printUser(pluginsPageWithCondition.getList()));
}

Service业务类信息


/**
 * 带条件 查询分页
 */
PageInfo<UserInfoPO> pluginsPageWithCondition(Page page);
===========================================

@Override
public PageInfo<UserInfoPO> pluginsPageWithCondition(Page page) {
    PageHelper.startPage(page.getPageNumber(), page.getPageSize());

    Example example = new Example(UserInfoPO.class);
    example.createCriteria()
            //年龄 > 10 岁
            .andGreaterThan("age", 10);
    example.orderBy("age").asc();

    List<UserInfoPO> userInfoPOS = mapper.selectByExample(example);
    return new PageInfo<>(userInfoPOS);

执行 curl 127.0.0.1:8800/temp/query11?pageNumber=3

查询结果

==>  Preparing: SELECT count(0) FROM user_info WHERE ((age > ?)) 
==> Parameters: 10(Integer)
<==    Columns: count(0)
<==        Row: 11
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2db58827]
2023-02-12 00:37:04.619  INFO 8496 --- [nio-8800-exec-2] c.j.tdmybatis.controller.TestController  :  pluginsPageWithCondition 第3页 数据 
:UserInfoPO{id=3, userId='33', userName='cc', age=31, address='广州'}
UserInfoPO{id=6, userId='66', userName='ff', age=34, address='西安'}
UserInfoPO{id=14, userId='456', userName='nn', age=34, address='上海'}

第三页 结果的确是 3,6,14 是按照 查询结果的 分页来处理的 image.png