MyBatis使用PageHelper排序分页
文章目录
- MyBatis使用PageHelper排序分页
- 前言
- 排序分页
- 使用PageHelper排序分页
- 添加PageHelper Spring Boot依赖
- 新增一个列表查询的方法
- 使用PageHelper来设置排序分页查询条件
- 测试和查看日志
- 参考文档
MyBatis使用PageHelper排序分页
前言
前面说明了:
- Spring Boot使用MyBatis访问MySQL
- Spring Boot统一REST API接口响应格式和异常处理
本文说明如何使用PageHelper对查询结果进行排序分页。
排序分页
排序分页常用于列表展示,打开列表时会先根据默认排序进行排序,然后再对记录进行分页展示,包括显示页数、每页显示的记录数和总记录数。用户可以选择排序方式,查看第几页的内容,修改每页可展示的记录数。
根据排序分页的实现,可以分为客户端排序分页和服务端排序分页。
- 客户端排序分页:也就是前端排序分页,后端直接返回默认排序的全部数据,再由前端组件来进行排序分页。客户端排序分页比较灵活,但是一般只用于数据量较少的情况。
- 服务端排序分页:也就是后端排序分页,后端在数据库中执行
select count
来获取总记录数,并利用数据库的特性进行分页(比如MySQL的limit
和offset
)。服务端排序分页性能较好,但是实现比较复杂。
PageHelper是MyBatis的服务端排序方式。
使用PageHelper排序分页
添加PageHelper Spring Boot依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
</dependency>
新增一个列表查询的方法
在UserMapper中新增一个列表查询的方法:
List<User> listUsers(User user);
其对应的Mapper XML为:
<select id="listUsers" parameterType="me.cookcode.springboot.mybatisdemo.model.User" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_user
where 1=1
<if test="name != null">
and `name` like concat('%', #{name,jdbcType=VARCHAR}, '%')
</if>
<if test="email != null">
and email like concat('%', #{email,jdbcType=VARCHAR}, '%')
</if>
</select>
- 该列表查询支持根据name和email做模糊查询,并返回全部符合条件的user
使用PageHelper来设置排序分页查询条件
从上面的Mapper XML中可以看到,SQL语句中并没有select count
、limit
和order by
语句。这些排序分页查询条件都是通过PageHelper“动态注入”的。
PageHelper排序分页示例:
@PostMapping("/users")
public ApiResponse getUsers(@RequestParam(value = "pageNum", defaultValue = "0") int pageNum,
@RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
@RequestParam(value = "orderBy", defaultValue = "name") String orderBy,
@RequestParam(value = "order", defaultValue = "asc") String order,
@RequestBody User user) {
// 设置pageSize最大值
if (pageSize > 50) {
pageSize = 50;
}
// 只允许指定的排序字段和排序方式,防止SQL注入
String[] orderByArr = { "name", "email"};
String orderByStr = "";
if (StringUtils.isNotEmpty(orderBy) && Arrays.asList(orderByArr).contains(orderBy.toLowerCase())) {
orderByStr = String.format("%s %s", orderBy.toLowerCase(), "asc".equalsIgnoreCase(order) ? "asc" : "desc");
} else {
// 默认排序
orderByStr = "name asc";
}
PageHelper.startPage(pageNum, pageSize, orderByStr);
List<User> users = userMapper.listUsers(user);
PageInfo<User> userPageInfo = new PageInfo<>(users);
return ApiResponse.success(userPageInfo);
}
为了简化自定义排序,也可以限制排序的种类,比如只支持“默认排序”、“播放多”、“新发布”和“弹幕多”,然后在Mapper XML中针对不同的排序种类来设定不同的
order by
来简化排序,并防止SQL注入。
测试和查看日志
假设已经安装好IDEA的Restful Toolkit和MyBatis Log Plugin。
打开Tools / MyBatis Log Plugin可以查看到真正执行的排序分页SQL日志。
打开 View / Tools Windows / RestServices,就可以方便地对上面的REST API进行测试。
SQL日志示例:
-- 查询记录总数
SELECT count(0)
FROM t_user
WHERE 1 = 1 AND `name` LIKE concat('%', '张', '%');
-- 查询排序分页记录结果
SELECT id, `name`, email
FROM t_user
WHERE 1 = 1 AND `name` LIKE concat('%', '张', '%') order by name desc
LIMIT 2;
REST API返回的接口响应示例:
{
"code": 0,
"message": "OK",
"data": {
"total": 3,
"list": [
{
"id": 11,
"name": "张翠山",
"email": "cuishan@example.com"
},
{
"id": 10,
"name": "张无忌",
"email": "wuji@example.com"
}
],
"pageNum": 1,
"pageSize": 2,
"size": 2,
"startRow": 1,
"endRow": 2,
"pages": 2,
"prePage": 0,
"nextPage": 2,
"isFirstPage": true,
"isLastPage": false,
"hasPreviousPage": false,
"hasNextPage": true,
"navigatePages": 8,
"navigatepageNums": [
1,
2
],
"navigateFirstPage": 1,
"navigateLastPage": 2
}
}
参考文档
- PageHelper Spring Boot
- MyBatis Spring Boot
- MyBatis中文文档
- MySQL中使用LIMIT进行分页的方法
- MySQL LIMIT以及LIMIT OFFSET 使用方法介绍
还没有评论,来说两句吧...