PageHelper的使用

PageHelper是Mybatis的分页插件,通过拦截器修改SQL实现分页。配置文件和包导入后,有两种使用方式:返回PageInfo对象或直接返回list。PageHelper.startPage()方法在SQL执行前修改SQL,实现分页。该方法的作用域限于当前线程的下一条查询SQL,而非整个线程中的所有查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PageHelper的使用

pagehelper是一个分页插件,其工作原理是利用mybatis拦截器,在查询数据库的时候拦截下sql,修改sql使其实现分页效果。

一:配置文件和包

​ pom.xml引入:

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

​ yml:

pagehelper:
  helper-dialect: mysql
  reasonable: true
  support-methods-arguments: true
二:使用方法:

​ 方式1:返回pageInfo

@GetMapping("/test1")
@ResponseBody
public PageInfo<Type> getType1(Integer pageNum){
    if (pageNum == null) pageNum =1;
    PageHelper.startPage(pageNum,5);
    List<Type> types = typeService.listType();
    PageInfo<Type> pageInfo = new PageInfo<>(types);
    return pageInfo;
}

​ 方式2:返回list

@GetMapping("/test2")
@ResponseBody
public List<Type> getType2(Integer pageNum){
    if (pageNum == null) pageNum =1;
    PageHelper.startPage(pageNum,5);
    List<Type> types = typeService.listType();
    return types;
}

测试接口分析其不同点:

​ 测试方式1:

在这里插入图片描述

{
    "total": 8,
    "list": [
        {
            "id": 3,
            "name": "分布式"
        },
        {
            "id": 4,
            "name": "微服务"
        },
        {
            "id": 5,
            "name": "大数据"
        },
        {
            "id": 6,
            "name": "spring全家桶"
        },
        {
            "id": 7,
            "name": "C语言回顾"
        }
    ],
    "pageNum": 1,
    "pageSize": 5,
    "size": 5,
    "startRow": 1,
    "endRow": 5,
    "pages": 2,
    "prePage": 0,
    "nextPage": 2,
    "isFirstPage": true,
    "isLastPage": false,
    "hasPreviousPage": false,
    "hasNextPage": true,
    "navigatePages": 8,
    "navigatepageNums": [
        1,
        2
    ],
    "navigateFirstPage": 1,
    "navigateLastPage": 2
}

测试方式2:

在这里插入图片描述

[
    {
        "id": 3,
        "name": "分布式"
    },
    {
        "id": 4,
        "name": "微服务"
    },
    {
        "id": 5,
        "name": "大数据"
    },
    {
        "id": 6,
        "name": "spring全家桶"
    },
    {
        "id": 7,
        "name": "C语言回顾"
    }
]

很明显,pageInfo附带了相关页的信息。

三:考虑方式2中的分页

​ 为什么添加了PageHelper.startPage()方法后就可以达到分页,PageHelper帮我们做了什么?

public String getPageSql(String sql) {
    StringBuilder sqlBuilder = new StringBuilder(sql.length() + 120);
    sqlBuilder.append("select * from ( select tmp_page.*, rownum row_id from ( ");
    sqlBuilder.append(sql);
    sqlBuilder.append(" ) tmp_page where rownum <= ? ) where row_id > ?");
    return sqlBuilder.toString();
}

pagehelper在执行sql前帮我们修改了sql。

通过控制台我们可以看到sql语句如下:
在这里插入图片描述

我们测试(debug)一遍接口:
Test:
在这里插入图片描述
在debug过程中可以看到:

在这里插入图片描述
pagehelper计算了limit 限制的起始行和结束行

四: PageHelper.startPage()方法的作用域

我们做一个这样的测试:

 //test
    @GetMapping("/test1")
    @ResponseBody
    public PageInfo<Type> getType1(Integer pageNum){
        if (pageNum == null) pageNum =1;
        PageHelper.startPage(pageNum,5);
        List<Type> types = getType3();
        PageInfo<Type> pageInfo = new PageInfo<>(types);
        return pageInfo;
    }

    public List<Type> getType3(){
        List<Type> types = typeService.listType();
        return types;
    }

问题: 方法1中设置了分页但未执行sql,方法2未设置分页但执行了sql,方法1调用方法2

测试/text1接口发现是可以得到数据的,进入startPage()查看:

在这里插入图片描述
在这里插入图片描述
显然,startPage()作用于一个线程内,那么思考是否startPage()作用于该线程内的所有sql查询?

测试:

 @GetMapping("/test1")
    @ResponseBody
    public PageInfo<Type> getType1(Integer pageNum){
        if (pageNum == null) pageNum =1;
        PageHelper.startPage(pageNum,5);
        List<Type> types = getType3();
        PageInfo<Type> pageInfo = new PageInfo<>(types);
        List<Type> types1 = typeService.listType();
        PageInfo<Type> pageInfo1 = new PageInfo<>(types1);
        return pageInfo1;
    }

通过postman测试接口发现并未分页

结论:startPage()作用于一个线程中的下一条查询sql

**注:**一次http请求,Java会开启一个线程处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值