• 关于 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="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://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 ,如下

      使用如下

      查询到数据的分页

      我们先来看如下案例

      初始数据有 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

  • 相关阅读:
    QQ集体被盗号,猝不及防的大型社死名场面
    02-Flask-对象初始化参数
    ICCV 2023 | MoCoDAD:一种基于人体骨架的运动条件扩散模型,实现高效视频异常检测
    uni-app:自带的消息提示被遮挡的解决办法(自定义消息提示框)
    竞赛 基于视觉的身份证识别系统
    (Vue笔记)VSCode创建与运行 Vue-cli + @Vue-cli 项目
    网络安全(黑客)自学
    ROS学习笔记一(安装、节点、发布者和订阅者)
    抖音视频评论批量采集软件|视频数据提取工具
    将 Ordinals 与比特币智能合约集成:第 4 部分
  • 原文地址:https://www.cnblogs.com/youzhibing/p/16246552.html