一、分页功能分析
此部分建议参考课程视频,讲解更加清楚明了!
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 = 23
,pageSize = 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
沉下去,静待花开!