MyBatis使用PageHelper排序分页

Myth丶恋晨 2023-07-17 15:48 41阅读 0赞

文章目录

  • MyBatis使用PageHelper排序分页
    • 前言
    • 排序分页
    • 使用PageHelper排序分页
      • 添加PageHelper Spring Boot依赖
      • 新增一个列表查询的方法
      • 使用PageHelper来设置排序分页查询条件
      • 测试和查看日志
    • 参考文档

MyBatis使用PageHelper排序分页

前言

前面说明了:

  • Spring Boot使用MyBatis访问MySQL
  • Spring Boot统一REST API接口响应格式和异常处理

本文说明如何使用PageHelper对查询结果进行排序分页。

排序分页

排序分页常用于列表展示,打开列表时会先根据默认排序进行排序,然后再对记录进行分页展示,包括显示页数、每页显示的记录数和总记录数。用户可以选择排序方式,查看第几页的内容,修改每页可展示的记录数。

根据排序分页的实现,可以分为客户端排序分页和服务端排序分页。

  • 客户端排序分页:也就是前端排序分页,后端直接返回默认排序的全部数据,再由前端组件来进行排序分页。客户端排序分页比较灵活,但是一般只用于数据量较少的情况。
  • 服务端排序分页:也就是后端排序分页,后端在数据库中执行select count来获取总记录数,并利用数据库的特性进行分页(比如MySQL的limitoffset)。服务端排序分页性能较好,但是实现比较复杂。

PageHelper是MyBatis的服务端排序方式。

使用PageHelper排序分页

添加PageHelper Spring Boot依赖

  1. <dependency>
  2. <groupId>com.github.pagehelper</groupId>
  3. <artifactId>pagehelper-spring-boot-starter</artifactId>
  4. <version>1.2.13</version>
  5. </dependency>

新增一个列表查询的方法

在UserMapper中新增一个列表查询的方法:

  1. List<User> listUsers(User user);

其对应的Mapper XML为:

  1. <select id="listUsers" parameterType="me.cookcode.springboot.mybatisdemo.model.User" resultMap="BaseResultMap">
  2. select
  3. <include refid="Base_Column_List" />
  4. from t_user
  5. where 1=1
  6. <if test="name != null">
  7. and `name` like concat('%', #{name,jdbcType=VARCHAR}, '%')
  8. </if>
  9. <if test="email != null">
  10. and email like concat('%', #{email,jdbcType=VARCHAR}, '%')
  11. </if>
  12. </select>
  • 该列表查询支持根据name和email做模糊查询,并返回全部符合条件的user

使用PageHelper来设置排序分页查询条件

从上面的Mapper XML中可以看到,SQL语句中并没有select countlimitorder by语句。这些排序分页查询条件都是通过PageHelper“动态注入”的。

PageHelper排序分页示例:

  1. @PostMapping("/users")
  2. public ApiResponse getUsers(@RequestParam(value = "pageNum", defaultValue = "0") int pageNum,
  3. @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
  4. @RequestParam(value = "orderBy", defaultValue = "name") String orderBy,
  5. @RequestParam(value = "order", defaultValue = "asc") String order,
  6. @RequestBody User user) {
  7. // 设置pageSize最大值
  8. if (pageSize > 50) {
  9. pageSize = 50;
  10. }
  11. // 只允许指定的排序字段和排序方式,防止SQL注入
  12. String[] orderByArr = { "name", "email"};
  13. String orderByStr = "";
  14. if (StringUtils.isNotEmpty(orderBy) && Arrays.asList(orderByArr).contains(orderBy.toLowerCase())) {
  15. orderByStr = String.format("%s %s", orderBy.toLowerCase(), "asc".equalsIgnoreCase(order) ? "asc" : "desc");
  16. } else {
  17. // 默认排序
  18. orderByStr = "name asc";
  19. }
  20. PageHelper.startPage(pageNum, pageSize, orderByStr);
  21. List<User> users = userMapper.listUsers(user);
  22. PageInfo<User> userPageInfo = new PageInfo<>(users);
  23. return ApiResponse.success(userPageInfo);
  24. }

为了简化自定义排序,也可以限制排序的种类,比如只支持“默认排序”、“播放多”、“新发布”和“弹幕多”,然后在Mapper XML中针对不同的排序种类来设定不同的order by来简化排序,并防止SQL注入。

测试和查看日志

假设已经安装好IDEA的Restful Toolkit和MyBatis Log Plugin。

打开Tools / MyBatis Log Plugin可以查看到真正执行的排序分页SQL日志。

打开 View / Tools Windows / RestServices,就可以方便地对上面的REST API进行测试。

SQL日志示例:

  1. -- 查询记录总数
  2. SELECT count(0)
  3. FROM t_user
  4. WHERE 1 = 1 AND `name` LIKE concat('%', '张', '%');
  5. -- 查询排序分页记录结果
  6. SELECT id, `name`, email
  7. FROM t_user
  8. WHERE 1 = 1 AND `name` LIKE concat('%', '张', '%') order by name desc
  9. LIMIT 2;

REST API返回的接口响应示例:

  1. {
  2. "code": 0,
  3. "message": "OK",
  4. "data": {
  5. "total": 3,
  6. "list": [
  7. {
  8. "id": 11,
  9. "name": "张翠山",
  10. "email": "cuishan@example.com"
  11. },
  12. {
  13. "id": 10,
  14. "name": "张无忌",
  15. "email": "wuji@example.com"
  16. }
  17. ],
  18. "pageNum": 1,
  19. "pageSize": 2,
  20. "size": 2,
  21. "startRow": 1,
  22. "endRow": 2,
  23. "pages": 2,
  24. "prePage": 0,
  25. "nextPage": 2,
  26. "isFirstPage": true,
  27. "isLastPage": false,
  28. "hasPreviousPage": false,
  29. "hasNextPage": true,
  30. "navigatePages": 8,
  31. "navigatepageNums": [
  32. 1,
  33. 2
  34. ],
  35. "navigateFirstPage": 1,
  36. "navigateLastPage": 2
  37. }
  38. }

参考文档

  • PageHelper Spring Boot
  • MyBatis Spring Boot
  • MyBatis中文文档
  • MySQL中使用LIMIT进行分页的方法
  • MySQL LIMIT以及LIMIT OFFSET 使用方法介绍

发表评论

表情:
评论列表 (有 0 条评论,41人围观)

还没有评论,来说两句吧...

相关阅读