SpringBoot-Mybatis-PageHelper分页使用

(1420条消息) 分页插件PageHelper工作原理_fedorafrog的博客-CSDN博客_pagehelper底层原理https://blog.csdn.net/fedorafrog/article/details/104412140 (1420条消息) PageHelper详解_32码奴的博客-CSDN博客_pagehelperhttps://blog.csdn.net/qq_45578181/article/details/119987379大数据量下 PageHelper 分页查询性能问题的解决办法_Java知音_的博客-CSDN博客作者:岁月安然blog.csdn.net/baidu_38083619/article/details/82463058前因项目一直使用的是PageHelper实现分页功能,项目前期数据量...https://dalin.blog.csdn.net/article/details/113733489?

(1420条消息) MyBatis分页插件pagehelper的使用以及其原理源码_Morning sunshine的博客-CSDN博客_mybatis pagehelper使用https://blog.csdn.net/qq_44750696/article/details/124075059 核心原理介绍:(1420条消息) PageHelper 分页原理_WeekDragon的博客-CSDN博客_分页插件pagehelper原理https://blog.csdn.net/jjzhoulong/article/details/125753953

1. 原理概述

PageHelper是MyBatis的一个插件,内部实现了一个PageInterceptor拦截器。Mybatis会加载这个拦截器到拦截器链中。在我们使用过程中先使用PageHelper.startPage这样的语句在当前线程上下文中设置一个ThreadLocal变量,再利用PageInterceptor这个分页拦截器拦截,从ThreadLocal中拿到分页的信息,如果有分页信息拼装分页SQL(limit语句等)进行分页查询,最后在PageInterceptor的finally 代码段中 调用 dialect.afterAll(),从而调用 PageHelper 的 clearPage方法  ,通过它把ThreadLocal中的东西清除掉。这也就是为什么 在调用了 startPage方法后,连续两句SQL只有第一句的分页生效的原因,因为第二句调用前 ThreadLocal中已经空了。

2. 使用注意事项

PageHelper使用了ThreadLocal保存分页参数,分页参数和线程是绑定的。因此我们需要保证PageHelper 的startPage调用后紧跟 MyBatis 查询方法,这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。

Service 方法调用SQL查询前添加 PageHelper.startPage

PageHelper.startPage(1, 20); 

这里有两个参数,分别为:page=1,rows=20。默认请求第一页,每页显示20条数据

先PageHelper.startPage(1, 10)开始分页,再selectlist查询数据库的时候会自动加上limit 1,10

得到这样的结果:查询结果也是会带上分页信息(已验证,你们可以自己去验证看一下)

首先是在Mybatis里面配置了分页拦截器(PageInterceptor),即在执行相关Sql之前会拦截做一点事情;

这里通过setLocalPage()方法,将分页信息保存在当前线程中。查询方法与之处于同一个线程中,共享ThreadLocal中的数据。

selectlist查询之后赋值给的List list。这个list是Page 类型。

再将list放到PageInfo<>中即可。

PageHelper

pagehelper是mybatis的一个插件,其作用是更加方便地进行分页查询

分页查询的实现有两种方式

1:直接在sql中使用 limit子句 进行分页查询

limit关键字的用法是:LIMIT [offset,] rows

select * from tableA limit 5,5;

Ps1:offset是相对于首行的偏移量(首行是0),rows是返回条数

Ps2:mapper中可以传变量,即在实际使用的时候 “offset与rows”可以用变量替代

2:使用第三方库进行分页查询,如mybatis的插件pagehelper

使用PageHelper的好处是在实际项目开发中更方便

原因是:在项目中我们执行一个分页查询时,很多时候还会需要知道该查询的其他信息,如总数、每页数量、当前页数、上一页或下一页等等,这些信息如果每次都自己写的话就太麻烦了,而pagehelper能够帮助我们更方便地获取这些信息,大大方便了我们的开发效率。

PageHelper在SpringBoot中的使用

一:导入插件

1:pom.xml中导入依赖

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

注意导入的依赖是spring版本的而不是其独立版本,否则pagehelper将不起作用

2:在springboot配置文件(applicable.yml)中声明插件

#pagehelper分页插件配置
pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql

二:在业务代码中使用

1:UserMapper

@Repository
@Mapper
public interface UserMapper {
    public List<User> selectAll();
}

2:UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.springboot.springboot_mybatis.mapper.UserMapper">
    <select id="selectAll" resultType="User">
        select * from user
    </select>
</mapper>

优点:不需要使用limit

3:实体类

4:service层

5:service实现类

@Service
public class QueryUser2 implements Query2 {
    @Autowired
    UserMapper userMapper;

    @Override
    public List<User> selectAll(int pageNum,int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<User> users = userMapper.selectAll();
        PageInfo<User> pageInfo = new PageInfo<>(users);
        return pageInfo.getList();
    }
}

注意:只有紧跟着PageHelper.startPage(pageNum,pageSize)的sql语句才被pagehelper起作用

再次注意:经过再次验证,上面这句话不是扯淡

6:control类

@RestController
public class controller3 {
    @Autowired
    Query2 query2;

    @GetMapping("/selectAll")
    public List<User> selectAll(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize){
        List<User> users = query2.selectAll(pageNum,pageSize);
        return users;
    }
}

使用中遇到的问题及tips:

1:在使用时pagehelper不起作用

注意pom.xml导入的依赖应该是spring版本的而不是其独立的版本

2:注意:只有紧跟着PageHelper.startPage()的sql语句才被pagehelper起作用

@Service
public class QueryUser2 implements Query2 {
    @Autowired
    UserMapper userMapper;

    @Override
    public List<User> selectAll(int pageNum,int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<User> users = userMapper.selectAll();
        System.out.println(users);
        List<User> users1 = userMapper.selectAll();
        System.out.println(users1);
        PageInfo<User> pageInfo = new PageInfo<>(users);
        return pageInfo.getList();
    }


}

控制台的输出

Page{count=true, pageNum=2, pageSize=2, startRow=2, endRow=4, total=8, pages=4, reasonable=true, pageSizeZero=false}[User{username='wangwu', age=20, address='fujian'}, User{username='dsdfds', age=23, address='eree'}]
[User{username='zhangsan', age=18, address='beijin'}, User{username='lisi', age=17, address='tianjing'}, User{username='wangwu', age=20, address='fujian'}, User{username='dsdfds', age=23, address='eree'}, User{username='dfwfd', age=22, address='dfdfd'}, User{username='dfdsettythg', age=45, address='ghgf'}, User{username='ggghgd', age=54, address='dfdf'}, User{username='dfdeg', age=21, address='fghgd'}]

可以看到只有紧跟着PageHelper.startPage()的那一句起了作用(注意,经过再次验证,这里不是扯淡,其原理可能是“PageHelper.startPage(pageNum,pageSize)在使用的时候启动了一个线程,致使了其能达到这个效果”)

注意,根据控制台可以得知,查询语句的返回结果“users”已经是分页之后的结果了,上面的例子没有写错;将users再传入PageInfo的目的是为了去除暂时用不到的其他信息,得到纯净的数据库信息:pageInfo.getList()

3:PageInfo的信息非常全,查询的个数、上一页、下一页等等信息都有,以上面springboot中的例子为例

PageInfo{pageNum=2, pageSize=2, size=2, startRow=3, endRow=4, total=8, pages=4, list=Page{count=true, pageNum=2, pageSize=2, startRow=2, endRow=4, total=8, pages=4, reasonable=true, pageSizeZero=false}[User{username='wangwu', age=20, address='fujian'}, User{username='dsdfds', age=23, address='eree'}], prePage=1, nextPage=3, isFirstPage=false, isLastPage=false, hasPreviousPage=true, hasNextPage=true, navigatePages=8, navigateFirstPage=1, navigateLastPage=4, navigatepageNums=[1, 2, 3, 4]}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值