MyBatis-Plus 分页查询中,即便 count 返回 0,为何仍需执行记录查询操作?

2026-05-06 05:531阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1694个文字,预计阅读时间需要7分钟。

MyBatis-Plus 分页查询中,即便 count 返回 0,为何仍需执行记录查询操作?

一开始,我初中高中时,中午午休的时候,常和哥们儿在网吧通宵打游戏。有人进来,哥们儿猛吸一口烟,然后把烟头扔了。进来的大多是老师,问我们:你们干吗呢?哥们儿一边从鼻孔里喷出烟雾,一边回答:干吗?玩儿呢!

开心一刻

  记得上初中,中午午休的时候,我和哥们躲在厕所里吸烟

  听见外面有人进来,哥们猛吸一口,就把烟甩了

  进来的是教导主任,问:你们干嘛呢?

  哥们鼻孔里一边冒着白烟一边说:我在生气

环境搭建   依赖引入

  MyBatis-Plus版本:3.1.0

  Spring Boot版本:2.1.0.RELEASE

  因为是基于Spring Boot,所以MyBatis-Plus的依赖如下

  完整pom.xml如下

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="maven.apache.org/POM/4.0.0" xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="maven.apache.org/POM/4.0.0 maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qsl</groupId> <artifactId>mybatis-plus-demo</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.0</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project> View Code   配置引入

  配置很简单,主要配置数据源和SQL打印,application.yml如下

spring: application: name: mybatis-plus-demo datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/my_project?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456 # SQL 打印,便于发现问题 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl View Code   表与初始数据

DROP TABLE IF EXISTS `tbl_user`; CREATE TABLE `tbl_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '姓名', `age` tinyint(3) NOT NULL COMMENT '年龄', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB; INSERT INTO `tbl_user` VALUES (1, '张三', 20); INSERT INTO `tbl_user` VALUES (2, '李四', 21); View Code   环境验证

  Service、Mapper就不写了,大家利用mybatis-plus-generator(版本与Mybatis-Plus版本保持一致)生成下就好

  嫌麻烦的也可以直接下载我的代码:mybatis-plus-demo

  我们来跑个简单案例看看MyBatis Plus是否搭建成功了

  可以看到,环境搭建是成功的

问题复现   分页插件

  既然是分页上的问题,自然要引入分页插件

  用的就是Mybatis Plus的分页插件:PaginationInterceptor

  分页查询也非常简单,Mybatis Plus提供了专门的api,如下

  使用如下

  查询到数据的分页

  我们先来看如下案例

MyBatis-Plus 分页查询中,即便 count 返回 0,为何仍需执行记录查询操作?

  初始数据有 2 条,我们来看看此案例的SQL输出

  一共两条SQL

  一条查询总数

  一条查询分页记录

  没毛病,稳如老狗

  未查询到数据的分页

  前面的案例是能够查到数据,如果查不到数据了?

  我们接着看另一个案例

  初始的 2 条数据中没有name = '吴用'的记录,那么此时的SQL输出是怎么样的了?

  同样输出两条SQL

  一条查询总数

  一条查询记录

  这有没有问题?大家想清楚再回答!

  肯定是有问题的,1、查询记录为什么不带分页参数,2、总记录数都是 0 了,为什么还去查记录

  2 个问题可以归为一个问题:总记录数都为 0 了,为什么还去查询记录?

源码分析

  我们代码都没写,问题肯定不是出在我们身上

(这锅甩的一点毛病没有!)

  既然是分页,那问题肯定出在分页插件上了!

  PaginationInterceptor实现了Mybatis的Interceptor接口

  问题分析

  那么分页逻辑肯定在PaginationInterceptor的intercept方法内(关于原因,大家可以去看:spring-boot-2.0.3源码篇 - pageHelper分页,绝对有值得你看的地方 以及与它相关的文章)

  我们来好好看看intercept方法

  关键代码

  问题就出在

  既然总记录条数都<= 0了,为什么还要往下走(继续查询记录),而不是直接返回null或者空集合?

  至此,相信大家都明白问题所在了

  官方修复

  3.1.0版本已经发布很久了

  这个问题不可能还未暴露,自此我特意去找了下Mybatis Plus的commit记录,还真让我找到了修复记录

  修复日期:2019/4/14,而版本3.1.1的发布日期:2019/4/26,也就是说这个问题在3.1.1中已经修复了,我们来验证下

  至此这个问题的来龙去脉,相信大家已经清楚了

总结

  1、大家选框架时,一定要注意版本

    最好能关注社区的问题讨论

    开源框架的话,大家可以关注Issues

    我们遇到的坑可能已经被别人踩过了,能够从中最快的找到解决方案

  2、随着版本的迭代,Mybatis Plus的分页插件实现有很大的改变,大家一定要结合应用的版本采用合适的分页插件

    感兴趣的可以去看看各个发布版本的改动,releases

标签:探讨C

本文共计1694个文字,预计阅读时间需要7分钟。

MyBatis-Plus 分页查询中,即便 count 返回 0,为何仍需执行记录查询操作?

一开始,我初中高中时,中午午休的时候,常和哥们儿在网吧通宵打游戏。有人进来,哥们儿猛吸一口烟,然后把烟头扔了。进来的大多是老师,问我们:你们干吗呢?哥们儿一边从鼻孔里喷出烟雾,一边回答:干吗?玩儿呢!

开心一刻

  记得上初中,中午午休的时候,我和哥们躲在厕所里吸烟

  听见外面有人进来,哥们猛吸一口,就把烟甩了

  进来的是教导主任,问:你们干嘛呢?

  哥们鼻孔里一边冒着白烟一边说:我在生气

环境搭建   依赖引入

  MyBatis-Plus版本:3.1.0

  Spring Boot版本:2.1.0.RELEASE

  因为是基于Spring Boot,所以MyBatis-Plus的依赖如下

  完整pom.xml如下

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="maven.apache.org/POM/4.0.0" xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="maven.apache.org/POM/4.0.0 maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qsl</groupId> <artifactId>mybatis-plus-demo</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.0</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project> View Code   配置引入

  配置很简单,主要配置数据源和SQL打印,application.yml如下

spring: application: name: mybatis-plus-demo datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/my_project?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456 # SQL 打印,便于发现问题 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl View Code   表与初始数据

DROP TABLE IF EXISTS `tbl_user`; CREATE TABLE `tbl_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '姓名', `age` tinyint(3) NOT NULL COMMENT '年龄', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB; INSERT INTO `tbl_user` VALUES (1, '张三', 20); INSERT INTO `tbl_user` VALUES (2, '李四', 21); View Code   环境验证

  Service、Mapper就不写了,大家利用mybatis-plus-generator(版本与Mybatis-Plus版本保持一致)生成下就好

  嫌麻烦的也可以直接下载我的代码:mybatis-plus-demo

  我们来跑个简单案例看看MyBatis Plus是否搭建成功了

  可以看到,环境搭建是成功的

问题复现   分页插件

  既然是分页上的问题,自然要引入分页插件

  用的就是Mybatis Plus的分页插件:PaginationInterceptor

  分页查询也非常简单,Mybatis Plus提供了专门的api,如下

  使用如下

  查询到数据的分页

  我们先来看如下案例

MyBatis-Plus 分页查询中,即便 count 返回 0,为何仍需执行记录查询操作?

  初始数据有 2 条,我们来看看此案例的SQL输出

  一共两条SQL

  一条查询总数

  一条查询分页记录

  没毛病,稳如老狗

  未查询到数据的分页

  前面的案例是能够查到数据,如果查不到数据了?

  我们接着看另一个案例

  初始的 2 条数据中没有name = '吴用'的记录,那么此时的SQL输出是怎么样的了?

  同样输出两条SQL

  一条查询总数

  一条查询记录

  这有没有问题?大家想清楚再回答!

  肯定是有问题的,1、查询记录为什么不带分页参数,2、总记录数都是 0 了,为什么还去查记录

  2 个问题可以归为一个问题:总记录数都为 0 了,为什么还去查询记录?

源码分析

  我们代码都没写,问题肯定不是出在我们身上

(这锅甩的一点毛病没有!)

  既然是分页,那问题肯定出在分页插件上了!

  PaginationInterceptor实现了Mybatis的Interceptor接口

  问题分析

  那么分页逻辑肯定在PaginationInterceptor的intercept方法内(关于原因,大家可以去看:spring-boot-2.0.3源码篇 - pageHelper分页,绝对有值得你看的地方 以及与它相关的文章)

  我们来好好看看intercept方法

  关键代码

  问题就出在

  既然总记录条数都<= 0了,为什么还要往下走(继续查询记录),而不是直接返回null或者空集合?

  至此,相信大家都明白问题所在了

  官方修复

  3.1.0版本已经发布很久了

  这个问题不可能还未暴露,自此我特意去找了下Mybatis Plus的commit记录,还真让我找到了修复记录

  修复日期:2019/4/14,而版本3.1.1的发布日期:2019/4/26,也就是说这个问题在3.1.1中已经修复了,我们来验证下

  至此这个问题的来龙去脉,相信大家已经清楚了

总结

  1、大家选框架时,一定要注意版本

    最好能关注社区的问题讨论

    开源框架的话,大家可以关注Issues

    我们遇到的坑可能已经被别人踩过了,能够从中最快的找到解决方案

  2、随着版本的迭代,Mybatis Plus的分页插件实现有很大的改变,大家一定要结合应用的版本采用合适的分页插件

    感兴趣的可以去看看各个发布版本的改动,releases

标签:探讨C