2025/2/24 下午《尚硅谷》——分页插件—— PageHelper和PageInfo<T>

一、分页功能分析

        此部分建议参考课程视频,讲解更加清楚明了!

1. 分页参数

  • pageSize: 每页显示的记录数。

  • pageNum: 当前页码。

  • index: 当前页的起始索引,计算公式为 index = (pageNum - 1) * pageSize

  • count: 总记录数。

  • totalPage: 总页数,计算公式为 totalPage = count / pageSize,如果 count % pageSize != 0,则 totalPage 需要加 1。

2. 分页查询

在 SQL 查询中,通常使用 LIMIT 子句来实现分页。LIMIT 子句的语法为 LIMIT offset, count,其中:

  • offset 是起始索引(即 index)。

  • count 是每页显示的记录数(即 pageSize)。

3. 示例

假设每页显示 4 条记录(pageSize = 4),以下是不同页码的分页查询示例:

  • pageNum = 1:

    • index = (1 - 1) * 4 = 0

    • SQL 查询: LIMIT 0, 4

    • 解释: 查询第 1 页,从第 0 条记录开始,显示 4 条记录。

  • pageNum = 3:

    • index = (3 - 1) * 4 = 8

    • SQL 查询: LIMIT 8, 4

    • 解释: 查询第 3 页,从第 8 条记录开始,显示 4 条记录。

  • pageNum = 6:

    • index = (6 - 1) * 4 = 20

    • SQL 查询: LIMIT 20, 4

    • 解释: 查询第 6 页,从第 20 条记录开始,显示 4 条记录。

4. 总页数计算

假设总记录数 count = 23pageSize = 4,则总页数计算如下:

  • totalPage = 23 / 4 = 5(整数部分)

  • 由于 23 % 4 = 3 != 0,所以 totalPage += 1,最终 totalPage = 6

5. 分页逻辑总结

  • 起始索引计算index = (pageNum - 1) * pageSize

  • 总页数计算totalPage = count / pageSize,如果 count % pageSize != 0,则 totalPage += 1

  • SQL 查询LIMIT index, pageSize

6. 注意事项

  • 页码越界: 当 pageNum 大于 totalPage 时,应返回空结果或提示用户无数据。

  • 性能优化: 对于大数据量的分页查询,建议使用索引或其他优化手段来提高查询效率。

二、分页插件使用步骤

1、添加依赖——pom.xml代码

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.2.0</version>
</dependency>

2、配置分页插件——mybatis-config.xml代码

<plugins>
    <!-- 设置分页插件 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
  • 作用:将 PageHelper 插件注册到 MyBatis 的插件链中,使其能够拦截 SQL 并自动添加分页逻辑。

  • 注意:如果使用 Spring Boot,可以通过配置文件(如 application.yml)配置插件,无需修改 mybatis-config.xml

3、实例演示

PageTest.java测试代码

package com.atguigu.mybatis.test;

import com.atguigu.mybatis.mapper.EmpMapper;
import com.atguigu.mybatis.pojo.Emp;
import com.atguigu.mybatis.utils.SqlSessionUtil;
import com.github.pagehelper.PageHelper;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class PageTest {

    @Test
    public void testPage() {
        // 获取 SqlSession 对象
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        // 获取 Mapper 接口实例
        EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);

        // 在查询功能之前开启分页
        // 参数说明:PageHelper.startPage(pageNum, pageSize)
        // pageNum:当前页码,pageSize:每页显示的记录数
        PageHelper.startPage(1, 4);

        // 执行查询
        List<Emp> list = mapper.selectByExample(null);

        // 输出查询结果
        list.forEach(System.out::println);
    }
}

4、测试输出

DEBUG 02-24 17:30:18,577 Cache Hit Ratio [SQL_CACHE]: 0.0 (LoggingCache.java:60) 
DEBUG 02-24 17:30:18,625 ==>  Preparing: SELECT count(0) FROM t_emp (BaseJdbcLogger.java:137) 
DEBUG 02-24 17:30:18,649 ==> Parameters:  (BaseJdbcLogger.java:137) 
DEBUG 02-24 17:30:18,670 <==      Total: 1 (BaseJdbcLogger.java:137) 
DEBUG 02-24 17:30:18,672 ==>  Preparing: select emp_id, emp_name, age, gender, dept_id from t_emp LIMIT ? (BaseJdbcLogger.java:137) 
DEBUG 02-24 17:30:18,673 ==> Parameters: 4(Integer) (BaseJdbcLogger.java:137) 
DEBUG 02-24 17:30:18,678 <==      Total: 4 (BaseJdbcLogger.java:137) 
Emp{empId=1, empName='李华', age=null, gender='null', deptId=null}
Emp{empId=2, empName='张三', age=null, gender='null', deptId=null}
Emp{empId=3, empName='杨哈哈', age=null, gender='null', deptId=null}
Emp{empId=4, empName='王五', age=null, gender='null', deptId=null}

进程已结束,退出代码为 0

5. 代码和输出分析

5.1分页逻辑

  • PageHelper.startPage(1, 4):开启分页,查询第 1 页,每页显示 4 条记录。

  • PageHelper 会自动拦截后续的查询 SQL,并添加 LIMIT 子句。

  • 例如,原始 SQL 为 select emp_id, emp_name, age, gender, dept_id from t_emp,分页后会变为:

select emp_id, emp_name, age, gender, dept_id from t_emp LIMIT 4

5.2分页查询过程

  • 先执行 SELECT count(0) FROM t_emp,获取总记录数(用于计算总页数)。

  • 再执行分页查询,返回当前页的数据。

5.3输出结果

  • 查询结果只包含第 1 页的 4 条记录。

  • 输出对象为 Emp,字段值为数据库中的对应数据。

6. 注意事项

6.1分页开启时机

  • PageHelper.startPage(pageNum, pageSize) 必须在查询方法之前调用,否则分页不会生效。

6.2分页参数

  • pageNum:当前页码,从 1 开始。

  • pageSize:每页显示的记录数。

6.3性能优化

  • 对于大数据量的分页查询,建议在 SQL 中添加索引,避免全表扫描。

6.4分页结果封装

  • PageHelper 返回的 List 是一个分页对象(Page),可以通过 PageInfo 获取更多分页信息(如总页数、总记录数等)。

三、通过分页插件获取分页相关数据

1. 获取分页相关信息

在查询数据库并获取分页后的 list 集合之后,可以使用 PageInfo<T> 类来获取分页的详细信息。

  • list:分页之后的数据集合。

  • navigatePages:导航分页的页码数(即页面底部显示的页码数量)。

// 示例:获取分页相关信息
PageInfo<User> pageInfo = new PageInfo<>(userList, 5);
2. 分页相关数据详解

PageInfo 类提供了丰富的分页信息属性,以下是常用属性及其含义:

属性名称 含义描述
pageNum 当前页的页码。
pageSize 每页显示的条数。
size 当前页显示的真实条数(可能小于 pageSize,例如最后一页)。
total 总记录数(即数据库中符合条件的数据总条数)。
pages 总页数(根据 total 和 pageSize 计算得出)。
prePage 上一页的页码。
nextPage 下一页的页码。
isFirstPage 是否为第一页(true 表示当前页是第一页)。
isLastPage 是否为最后一页(true 表示当前页是最后一页)。
hasPreviousPage 是否存在上一页(true 表示存在上一页)。
hasNextPage 是否存在下一页(true 表示存在下一页)。
navigatePages 导航分页的页码数(即页面底部显示的页码数量)。
navigatepageNums 导航分页的页码列表(如 [1, 2, 3, 4, 5],用于页面底部的页码显示)。

3. 代码示例

以下是一个完整的代码示例,展示如何获取分页相关信息并输出:

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import java.util.List;

public class PaginationExample {

    public static void main(String[] args) {
        // 模拟查询第2页,每页显示10条数据
        int pageNum = 2;
        int pageSize = 10;

        // 开启分页功能
        PageHelper.startPage(pageNum, pageSize);

        // 模拟查询数据库获取数据列表
        List<User> userList = userMapper.selectAll();

        // 获取分页相关信息,设置导航分页的页码数为5
        PageInfo<User> pageInfo = new PageInfo<>(userList, 5);

        // 输出分页相关信息
        System.out.println("当前页码: " + pageInfo.getPageNum());
        System.out.println("每页显示条数: " + pageInfo.getPageSize());
        System.out.println("当前页真实条数: " + pageInfo.getSize());
        System.out.println("总记录数: " + pageInfo.getTotal());
        System.out.println("总页数: " + pageInfo.getPages());
        System.out.println("上一页页码: " + pageInfo.getPrePage());
        System.out.println("下一页页码: " + pageInfo.getNextPage());
        System.out.println("是否为第一页: " + pageInfo.isIsFirstPage());
        System.out.println("是否为最后一页: " + pageInfo.isIsLastPage());
        System.out.println("是否存在上一页: " + pageInfo.isHasPreviousPage());
        System.out.println("是否存在下一页: " + pageInfo.isHasNextPage());
        System.out.println("导航分页页码: " + pageInfo.getNavigatepageNums());
    }
}
4. 输出结果示例

假设总记录数为 30 条,每页显示 10 条数据,当前页码为 2,导航分页的页码数为 5,则输出结果可能如下:

当前页码: 2
每页显示条数: 10
当前页真实条数: 10
总记录数: 30
总页数: 3
上一页页码: 1
下一页页码: 3
是否为第一页: false
是否为最后一页: false
是否存在上一页: true
是否存在下一页: true
导航分页页码: [1, 2, 3]

mybatis部分完结撒花,学习最近出现浮躁,烦!!    耗时2025/2/19——2025/2/24  19:36:36

沉下去,静待花开!