大型项目中获取数据的体量一般很大,在前段界面进行展示时为了保障展示效果,会要求接口快速返回,这时候后端一般会选择分页获取数据,只传递要查询的页码数据就可以。这种情况就避免了大部分的问题,达到快速返回的效果。
现阶段常用的分页有两种:
MyBatis
分页插件:PageHelper
,这个插件很常用,支持多数据库分页,无需修改SQL语句即可实现分页功能。- 注意:这个插件的功能相当于在你代码中的第一个 SQL 语句的后面加上
LIMIT [offset], [limit]
子句,例如LIMIT 20, 10
,表示从21条记录开始,获取10条记录。 - 这个插件
只会在你的第一条语句后面添加子句
,如果代码后面还存在其他的 SQL 则会不生效。 - 如果你使用这个插件获取
UserId
列表,并用该列表进行后续操作,要注意返回的顺序问题
。
- 注意:这个插件的功能相当于在你代码中的第一个 SQL 语句的后面加上
- 手动分页:
PageInfo
类。- 手动分页适合数据量小的情况,因为需要预先加载所有数据,例如预先加载所有
UserId
,对UserId
进行划分数量,根据请求的分页参数查询处在不同数量位置的UserId
。 - 详细可查看文章:SpringBoot 项目返回结果如何使用 PageInfo 类进行手动分页
- 手动分页适合数据量小的情况,因为需要预先加载所有数据,例如预先加载所有
本文只介绍分页插件 PageHelper
,包括使用的依赖,创建方式,代码示例和验证结果展示等。
文章目录
一、分页信息封装类 PageInfo 是什么?
我们在使用 MyBatis 分页时,不论是使用自动分页还是手动分页都会使用 PageInfo 对象作为承接介质。
PageInfo 是一个分页信息封装类,通常用于Web应用中的分页数据展示。它可以将分页查询结果和分页参数封装在一个对象中,便于传输和使用。我们使用时会遇到以下属性:
1、存储和管理分页相关的参数,自动分页时会自动设置,而手动分页时需要手动设置。
当前页码(pageNum
)、每页记录数(pageSize
)、总记录数(total
)、总页数(pages
)
2、分页导航信息参数
是否有上一页(hasPreviousPage
)、是否有下一页(hasNextPage
)、是否为第一页(isFirstPage
)、是否为最后一页(isLastPage
)、导航页码数组(navigatepageNums
)
3、PageInfo 作为后端返回给前端的标准分页数据格式,便于前端渲染分页组件。前端在使用时无需手动计算分页参数,如总页数、是否有下一页等,提高可读性和可维护性。
二、分页插件的两种依赖引入方式
1、使用 pagehelper 包
在项目中使用 PageHelper
插件需要先添加依赖,使用这种方式需要定义一个 config
文件。
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.3</version>
</dependency>
package com.wen.config;
import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class MyBatisConfig {
// 设置相关的参数信息,下面有对参数的详细解释
@Bean
public PageHelper pageHelper() {
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("dialect", "Mysql");
properties.setProperty("offsetAsPageNum", "true");
properties.setProperty("rowBoundsWithCount", "true");
pageHelper.setProperties(properties);
return pageHelper;
}
}
Properties
中需要设置的属性值的解释:
"dialect", "Mysql"
:不同数据库 SQL 语句不同,指定了数据库方言为Mysql
。"offsetAsPageNum", "true"
:这个属性通常用于指定是否将传入的offset
参数当作pageNum
页码使用。- 设置为
true
,意味着如果分页查询时传递了offset
偏移量,PageHelper
会将其视为页码来处理。 - 不是必需,因为
PageHelper
默认就是使用页码pageNum
和每页记录数pageSize
来进行分页的。
- 设置为
"rowBoundsWithCount", "true"
:这个属性用于指定是否进行count
查询以获取总记录数。- 在分页查询时,需要知道总记录数,它可以让你在前端展示总页数或总记录数。
- 设置为
true
表示PageHelper
在执行分页查询时,会先执行一个count
查询来获取总记录数。
2、使用 pagehelper-spring-boot-starter 启动
SpringBoot 起步依赖也封装了关于分页插件的依赖,需要在配置文件 application.properties
或 application.yml
中进行配置。
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
配置内容和上面使用配置类的方式一致。下面是两种配置文件的配置方式。
pagehelper.helper-dialect=mysql // 数据库 可选
pagehelper.reasonable=true // 规整页码范围,应对负数或过大页码
pagehelper.support-methods-arguments=true // 规整可以通过方法参数获取,可用可不用输入即可
pagehelper.params=count=countSql // 是否统计总数
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
三、创建示例展示使用分页插件
1、创建数据库表格示例
本文创建一个 tb_user
表,含有 id
、username
和password
字段。本文只做一个简单示例,不涉及复杂业务。
使用 pagehelper-spring-boot-starter
依赖时进行的分页条件配置。
pagehelper:
helper-dialect: mysql
reasonable: true // 规整页码范围
support-methods-arguments: true // 规整方法参数获取
下面代码中存在部分代码是项目中必须代码,如统一封装返回,MyBatis
项目搭建等就不在本文展示,有兴趣可查看以下文章。
关于统一 API 响应结果封装,代码示例在 SpringBoot 项目统一 API 响应结果封装 。
关于 MyBatis
的项目搭建在 SpringBoot 项目整合 MyBatis 框架 。
2、TestController
package com.wen.controller;
import com.wen.data.Result;
import com.wen.data.ResultGenerator;
import com.wen.dto.TbUser;
import com.wen.service.TestService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TestService testService;
@GetMapping("/select")
public Result<?> selectUserByPage(
@Param("pageSize") Integer pageSize,
@Param("pageNumber") Integer pageNumber){
return ResultGenerator.genSuccessResult(testService.selectUserByPage(pageSize, pageNumber));
}
}
3、TestService
package com.wen.service;
import com.github.pagehelper.PageInfo;
import com.wen.dto.TbUser;
public interface TestService {
PageInfo<TbUser> selectUserByPage(Integer pageSize, Integer pageNumber);
}
4、TbUserMapper
package com.wen.mapper;
import com.wen.dto.TbUser;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface TbUserMapper {
List<TbUser> selectUser();
}
5、TestServiceImpl
package com.wen.service.impl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wen.dto.TbUser;
import com.wen.mapper.TbUserMapper;
import com.wen.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TestServiceImpl implements TestService {
@Autowired
private TbUserMapper tbUserMapper;
@Override
public PageInfo<TbUser> selectUserByPage(Integer pageSize, Integer pageNumber) {
// 这句代码要放在查询 mapper 语句的前面,用于对数据库查询 SQL 添加分页。
PageHelper.startPage(pageNumber, pageSize);
List<TbUser> tbUsers = tbUserMapper.selectUser();
PageInfo<TbUser> tbUserPageInfo = new PageInfo<>(tbUsers);
return tbUserPageInfo;
}
}
6、TbUserMapper.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.wen.mapper.TbUserMapper">
<select id="selectUser" resultType="com.wen.dto.TbUser">
SELECT username, password FROM tb_user
</select>
</mapper>
四、使用不同的依赖展示结果会有差别
由下面的 JSON 结果可以看到数据的总数,页数,每页数据数量等,还有导航页面数据。
1、使用 pagehelper 依赖结果展示
http://localhost:8080/test/select?pageSize=5&pageNumber=1
JSON
数据格式。
{
"code": 1,
"message": "SUCCESS",
"data": {
"pageNum": 1,
"pageSize": 5,
"size": 5,
"orderBy": null,
"startRow": 1,
"endRow": 5,
"total": 7,
"pages": 2,
"list": [
{
"id": 0,
"username": "laowang",
"password": "112233"
},
{
"id": 0,
"username": "laoli",
"password": "123456"
},
{
"id": 0,
"username": "lisi",
"password": "3344"
},
{
"id": 0,
"username": "wangwu",
"password": "6677"
},
{
"id": 0,
"username": "周周",
"password": "111"
}
],
"firstPage": 1,
"prePage": 0,
"nextPage": 2,
"lastPage": 2,
"isFirstPage": true,
"isLastPage": false,
"hasPreviousPage": false,
"hasNextPage": true,
"navigatePages": 8,
"navigatepageNums": [
1,
2
]
}
}
2、使用 pagehelper-spring-boot-starter 依赖结果展示
http://localhost:8080/test/select?pageSize=5&pageNumber=1
JSON
数据格式。
{
"code": 1,
"message": "SUCCESS",
"data": {
"total": 7,
"list": [
{
"id": 0,
"username": "laowang",
"password": "112233"
},
{
"id": 0,
"username": "laoli",
"password": "123456"
},
{
"id": 0,
"username": "lisi",
"password": "3344"
},
{
"id": 0,
"username": "wangwu",
"password": "6677"
},
{
"id": 0,
"username": "周周",
"password": "111"
}
],
"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
}
}