PageHelper分页插件详解

前言:

最近小组给了需求,让写一个类似微博的系统,提高我们的开发能力和合作水平,但是里面的分页学长建议自己手写,并未用到分页插件,现在项目结束了,要改进一下,改用PageHelper插件来实现分页功能。

一、Mybatis分页查询的原理

MyBatis是一种Java持久层框架,用于简化与数据库的交互操作。在MyBatis中进行分页查询是常见的需求,MyBatis 分页查询的底层实现原理主要涉及两个方面:SQL 语句的拼接和数据库的分页查询。

1.在 MyBatis 中,我们可以通过在 SQL 语句中添加 LIMIT 或 OFFSET 语句来实现分页查询。LIMIT 用于限制返回的记录数量,OFFSET 则用于指定返回记录的起始位置。因此,我们只需要在 SQL 语句中添加这两个语句,就可以轻松地实现分页查询。如下:

方法一:SELECT * FROM your_table LIMIT #{pageSize} OFFSET #{offset}

方法二:SELECT * FROM your_table LIMIT #{offset},#{pageSize}

2.但是,在实际应用中,分页查询往往需要我们动态地生成 SQL 语句。MyBatis 提供了两种方式来实现动态 SQL 语句的生成:一种是使用 XML 配置文件中的 SQL 片段和动态 SQL 标签;另一种是使用注解。

3.当进行分页查询时,MyBatis 会根据传入的参数计算出需要返回的记录的数量和起始位置,并将这些信息封装成一个 Page 对象传递给底层的数据库查询引擎。数据库引擎则根据传入的 Page 对象进行分页查询,并返回相应的结果集。

4.因此,MyBatis 分页查询的底层实现原理可以概括为:根据传入的参数动态生成带有 LIMIT 和 OFFSET 的 SQL 语句,然后将生成的 SQL 语句传递给底层的数据库引擎进行查询,最终返回分页查询结果。

二、pageHelper分页插件的使用

springboot集成PageHelper分页插件:

1.导入依赖

    <!-- **********************  分页 Pom依赖 ********************** -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.1</version>
</dependency>

2.在springboot的配置文件里面配置相应的参数(application.properties格式)

pagehelper.helper-dialect=mysql #mysql方言
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true

3.使用实例:

方法一:返回PageInfo

ServiceImpl;

 @Override
    public PageInfo<User> testPageHelper(Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<User> userList = blogMapper.test();//调用mapper
        PageInfo<User> pageInfo = new PageInfo<>(userList);
        return pageInfo;
    }

Test:(获取到pageInfo对象,可以获取有关分页的信息)

 @Test
    public void test() {
        PageInfo<User> pageInfo = blogService.testPageHelper(1, 10);
        System.out.println(pageInfo.getPages());//总的页数
        System.out.println(pageInfo.getTotal());//总的记录数
        System.out.println(pageInfo);
    }

方法二:返回PageBean

PageBean实体类:

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "PageBean对象:分页实体类",description = "分页实体类")
public class PageBean {
    @ApiModelProperty(value = "总的记录数", name = "total")
    private Long total;
    @ApiModelProperty(value = "每页的数据,一个个对象", name = "rows")
    private List rows;
}

 ServiceImpl:

 @Override
    public PageBean testPageHelper(Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<User> userList = blogMapper.test();
        Page<User> page = (Page<User>) userList;
        return new PageBean(page.getTotal(),page.getResult());
    }

 test:

 @Test
    public void test() {
        PageBean pageBean = blogService.testPageHelper(1, 10);
        System.out.println(pageBean);
    }

注意,必须是调用查询方法之前就使用PageHelper.startPage,中间不能有其它的查询操作。因为PageHelper.startPage采用的是ThreadLocalL保存分页参数然后在执行查询数据库sql时,通过拦截器PageInterceptor在sql语句中添加了分页参数,达到分页的目的,执行新的sql获取分页结果,最后在finally方法中清空ThreadLocalL。

所以这里PageHelper有个隐患,如果设置了PageHelper.startPage,之后的查询语句如果出现异常,就导致PageHelper中的ThreadLocalL仍然具有分页参数,如果此时有一个非分页的查询语句进来,这个时候就该查询就会被分页(而本不应该需要分页)。

还有一点,在多数据源的情况下,也要注意pagehelper的使用,默认它只会在一个数据源中起作用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值