Mybatis Plus很好,但也有坑!

【MyBatis】 MyBatis与MyBatis-Plus的区别 mybatis-plus 是 mybatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 阅读详情

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

dd8d0efcfc7e7ebc8121a416ddc1eff0.gif

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:

  • Boot 地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 地址:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

来源:waynblog


最近在开发一个后台发送消息的功能时,由于需要给多个用户发送消息,于是使用了 mybatis plus 提供的 saveBatch() 方法,在测试环境测试通过上预发布后,测试反应发送消息接口很慢得等 5、6 秒,于是我就登录线上环境查看执行日志,发现是 mybatis plus 提供的 saveBatch() 方法执行很慢导致,于是也就有了本篇文章。

mybatis plus 是一个流行的 ORM 框架,它基于 mybatis,提供了很多便利的功能,比如代码生成器、通用 CRUD、分页插件、乐观锁插件等。它可以让我们更方便地操作数据库,减少重复的代码,提高开发效率。

案发现场还原

/**
 * 先保存通知消息,在批量保存用户通知记录
 */
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveNotice(Notify notify, String receiveUserIds) {
    long begin = System.currentTimeMillis();
    notify.setCreateTime(new Date());
    notify.setCreateBy(ShiroUtil.getSessionUid());
    if (notify.getPublishTime() == null) {
        notify.setPublishTime(new Date());
    }
    boolean insert = save(notify);
    List<NotifyRecord> collect = new ArrayList<>();
    List<String> receiveUserList = fillNotifyRecordList(notify, receiveUserIds, collect);
    notifyRecordService.saveBatch(collect);
    long end = System.currentTimeMillis();
    System.out.println(end - begin);
    ...
    return insert;
}

/**
 * 根据用户id,组装用户通知记录集合,返回200条记录
 */
public List<String> fillNotifyRecordList(Notify notify, String receiveUserIds, List<NotifyRecord> collect) {
    List<String> noticeRecordList = new ArrayList<>(200);
    ...
    // 组将两百条用户通知记录
    return noticeRecordList;
}

如上代码,我有一个 saveNotice() 方法用于保存通知消息以及用户通知记录。执行逻辑如下,

  1. 保存通知消息

  2. 根据用户 id,组装用户通知记录集合,返回 200 条用户通知记录

  3. 批量保存用户通知记录集合

前两步骤耗时都很少,我们直接看第三步操作耗时,结合 sql 执行日志,如下,

-- slow sql 5542 millis. INSERT INTO oa_notify_record  ( notifyId, receiveUserId, receiveUserName, isRead,  createTime )  VALUES  ( ?, ?, ?, ?,  ? )[225,"fcd90fe3990e505d07c90a238f75e9c1","niuwawa",false,"2023-10-30 23:54:04"]
5681

再结合 mybatis free log 插件打印完整 sql 如下图,

adb6047d3e314f045a73616e7dd6daf3.png

可以看出,我们批量保存用户通知记录是一条记录一条进行保存得,已经可以猜测就是批量插入方法导致得耗时较高。

这里使用得是 mybatis log free 插件,它可以自动帮我们在控制台打印完整得 mybatis sql 语句。有需要可以在 idea 插件中心搜索 mybatis log free 下载安装。

结合 saveBatch() 底层源码也能够看出,mybatis plus 对于批量操作是通过 for 循环执行保存操作得,源码如下图,

fb5dd78b8db4a9bf0edcd1fa8cc2e84e.png

到这里我们也就知道了在测试环境执行较快得原因,因为在测试环境需要批量保存得用户通知记录比较少,只有几条记录,所以很快。但是上预发布后,由于预发布中需要批量保存得用户通知记录比较多达到了数百条,所以执行较慢,耗时达到了 5、6 秒之久。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

解决方法

到这里,也就是本文得重点所在了,那怎么解决这个问题嘞?如何既利用 mybatis plus 提供得便携性,也能够解决批量操作耗时较高得问题。

其实解决方法很简单,只需要在 jdbcurl 上添加 rewriteBatchedStatements=true 参数即可解决这个问题。

MySQL 的 JDBC 连接的 url 中要加 rewriteBatchedStatements 参数,并保证 5.1.13 以上版本的驱动,才能实现高性能的批量插入。

MySQL JDBC 驱动在默认情况下会无视 executeBatch()语句,把我们期望批量执行的一组 sql 语句拆散,一条一条地发给 MySQL 数据库,批量插入实际上是单条插入,直接造成较低的性能。只有把 rewriteBatchedStatements 参数置为 true, 驱动才会帮你批量执行 SQL。另外这个选项对 INSERT/UPDATE/DELETE 都有效。

rewriteBatchedStatements=true 的意思是,当你在 Java 程序中使用批量插入/修改/删除(batching)时,MySQL JDBC 驱动程序将尝试重新编写(rewrite)你的 SQL 语句,以便更有效地执行这些批量插入操作。

OK,在我们给 jdbcurl 上添加了参数后,看看效果,如下图,

0c2ac034c8df346053153e37f40aaf88.png

可以看到 jdbcurl 添加了 rewriteBatchedStatements=true 参数后,批量操作的执行耗时已经只有 200 毫秒,自此也就解决了 mybatis plus 提供的 saveBatch() 方法执行耗时较高得问题。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

总结

mybatis plus 给开发人员带来了很多便利,但是其中也有一些坑点,比如上文所提到得批量操作耗时问题,如果不注意的话,就有可能调入坑里,各位开发同学可以检查自己或者公司项目中 jdbcurl 是否缺失 rewriteBatchedStatements=true 参数,加以改正,避免重复掉入这个坑里。


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,“长按”或“扫描”下方二维码噢:

4e4ea8713f0575cc877ac16c5f79da2e.png

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

ba8d69f456fa518fc82c2771114fae32.png

db137100be1b03270be08c618f7c5aac.png80b1450dc77463704979a4ccef5d587b.png817adfbfbb7704608acf11099226be0c.png76812a0b26cccd98601875cb728a0398.png

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
mybatis 和 mybatis-plus 配置文件: 用于配置数据库连接和 MyBatis 运行时所需的各种特性,包含了设置和影响 MyBatis 行为的属性、映射文件的位置。mapper接口和mapper.xml之间需要遵循一定规则,才能成功的让mybatis将mapper接口和mapper.xml绑定起来。创建IUserMapper接口: 用于操作数据库CURD的方法。文件:用于mybatis配置文件读取数据库信息。resources 目录下 创建。resources 目录下 创建。resources 目录下 的。类:用于跟数据库字段做映射。 阅读详情

相关推荐

mybatis-plus的坑

mybatis升级mybatis-plus时踩到的一些坑 前言 最近使用RuoYi-Vue来做后台管理脚手架。RuoYi-Vue 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源。其官方文档如下 http://doc.ruoyi.vip/ 感兴趣的朋友,可以点链接查看。

weixin_42609207的博客 2843

别在一直纠结MyBatis-Plus了,MyBatis才是真正的主人!

MyBatis工作原理及Mapper写法等等

左小涩° 1万+

Mybatis、Mybatis-plus框架

3、PageHelper插件:引入依赖、开启分页(PageHelper.startPage(pageNum,pageSize))、分装结果(PageInfo<~> pageInfo = new PageInfo<>(结果对象))通过XML或注解的方式将statement配置起来,用java对象与动态参数进行映射形成最终的执行语句,由Mybatis执行SQL语句,并将结果映射为java对象。半ORM(对象关系映射)框架,内部封装JDBC,只需关注SQL,严格控制SQL执行性能,灵活性高。

weixin_51877265的博客 1655

整合mybatis-plus必须避开的大坑

官网没有整合完整的例子,自己整合起来一通乱试,终于搞定,现在记录一下: 工程图: 1,去官网上找到导入maven的依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/X...

1万+

python画弗里德曼(Friedman) 检验和秩和检验(Nemenyi)检验图

python画弗里德曼(Friedman) 检验和秩和检验(Nemenyi)检验图 画好后效果图 实现代码如下 import matplotlib.pyplot as plt #算法平均排名 _alg_=[1.405,2.643,2.786,2.167] y=[1,2,3,4]#alg1,alg2,alg3,alg4 通过Nemenyi测试计算得到的临界值CD CD=1.024 h_CD=CD/2 plt.figure(figsize=(10,6)) plt.scatter(_alg_,y,s=10

大模型天花板 4465

从收音机到Arduino:手把手教你用BJT三极管搭建一个简易音频放大器(附电路图与元件清单)

本文详细介绍了如何使用BJT三极管搭建简易音频放大器,涵盖电路原理、元件选择、设计步骤及调试技巧。通过实践项目帮助电子爱好者深入理解BJT的放大特性,并提供与Arduino结合的扩展应用方案,适合创客和DIY玩家。

aitie1479的博客 443

为什么不建议你使用Mybatis-plus

整洁的代码意味着阅读代码的时间成本降低,但是如果使用MP,在你阅读service层代码时,还会看到在代码中拼装SQL执行条件的部分。如果是SQL语法错误,由于SQL语法错误在Java开发中错误日志非常显眼,所以你可以通过复制日志中报错的SQL然后代码全局搜索快速定位出错位置,而且SQL语法错误基本都是字段名写错或者执行条件顺序错误,这都是非常容易修改的BUG。你在纯Mybatis中会一次性将SQL写进XML文件中,如果在项目中这条SQL需要调用N次,你只需要在这N个地方都传参调用即可。...

web13170611647的博客 1万+

IDEA集成selenium自动化测试(Java+Selenuim+testNG+Maven)

文章目录写在前面01 | 新建Maven项目02 | idea集成Selenium03 | 写在前面 因为软件测试的需求和博主比较经常使用Java,于是,想在Idea中集成selenuim,用Java编写测试代码,因此有了这篇文章来记录一下过程。 资源指路: java使用selenium实现模拟浏览器操作API大全 模拟登录 TestNG入门教程 感谢上面博客的大佬。 01 | 新建Maven项目 不使用骨架创建,直接点击左侧Maven,然后一路next即可。 02 | idea集成Sele

aLinxi的博客 8281

服务端架构:Mybatis-Plus的优缺点

前段时间帮朋友处理java后端架构问题,看到了mybatis-plus,其实早几年就知道这个东西,但一直没用没学,这两天许久未见的web服务看了看,聊聊个人感受 如有不适,请见谅 文章目录优点缺点1.对数据访问层DAO的上层入侵太强,入侵到service、甚至controller!2.数据查询代码复杂,最终SQL黑盒,不清晰,不利于业务性优化,不利于排查问题 优点 本文没有优点介绍,若要看到优点,自己去官方文档看吧,全是优点,明明白白 缺点 两大缺点足以限制其在大规模服务中使用:入侵Service和Co.

maoyuanming0806的博客 1万+

基于ABCDRez的激光谐振腔设计与热透镜效应仿真实践

本文详细介绍了如何利用ABCDRez代码包进行激光谐振腔设计与热透镜效应仿真。通过ABCD矩阵理论和高斯光束q参数,该工具能有效模拟热透镜动态变化对腔稳定性的影响,指导腔型优化与热补偿设计,是固体激光器预研与调试的高效辅助手段。

weixin_29093017的博客 290

SWD下载调试接口原理深度剖析

作为ARM嵌入式工程师,下载调试器都应该知道,但你真正了解SWD如何下载调试的么?ARM 芯片通过什么物理接口和什么方式连接完全取决于芯片Debug子系统的架构如何?

zhuwade的博客 1万+

大佬的Mybatis-Plus使用技巧,带你避“坑”,实在太火了~

作者:Asurplus来源:lizhou.blog.youkuaiyun.com/article/details/108093246今天天就来说说 Mybatis-Plus 的那些使用技巧# 条件查...

JAVA葵花宝典 1145

苹果开发者账号( Apple Developer)登录出现:你的 Apple ID 暂时不符合使用此应用程序的条件(您的apple账户不符合资格)

Apple开发对于新手来说确实可能会遇到各种问题,在遇到 Apple Developer 账号登录问题时,除了检查账号的安全性设置和协议确认外,还需要考虑账号的具体配置问题,比如主邮箱的设置。

Winter_Sun灬的博客 4144

mybatis plus很好,但是我被它坑了!

给开发人员带来了很多便利,但是其中也有一些坑点,比如上文所提到得批量操作耗时问题,如果不注意的话,就有可能调入坑里,各位开发同学可以检查自己或者公司项目中jdbcurl是否缺失参数,加以改正,避免重复掉入这个坑里。关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、国外优质文章翻译等,您的关注将是我的更新动力!

Wayn111的博客 425

【数据集】CAMS 全球生物质燃烧排放 GFAS(基于火灾辐射功率)

CAMS 全球生物质燃烧排放 GFAS(基于火灾辐射功率)

WW、forever的博客 403

【华为OD机试】创建二叉树(python, java, c++, js)

请按下列描达构建一颗二叉树,并返回该树的根节点: 1、先创建值为-1的根结点,根节点在第0层; 2、然后根据operations依次添加节点: operations[i] = [height, index] 表示对第 height 层的第index 个节点node, 添加值为i 的子节点: 若node 无「左子节点」。则添加左子节点; 若node 有「左子节点」但无「右子节点」,则添加右子节点: 否则不作任何处理。 height、index 均从0开始计数;index 指所在层的创建顺序。

A_D_I_D_A_S的博客 190

mybatis plus很好,但是我被它坑了

mybatis plus 给开发人员带来了很多便利,但是其中也有一些坑点,比如上文所提到得批量操作耗时问题,如果不注意的话,就有可能调入坑里,各位开发同学可以检查自己或者公司项目中 jdbcurl 是否缺失 rewriteBatchedStatements=true 参数,加以改正,避免重复掉入这个坑里。

weixin_74412978的博客 1390

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

MyBatis Plus 如何实现连表查询 mybatis plus join

MyBatis-Plus 连表插件 mybati-plus-join, 完全按照mybats plus API风格扩展,支持一对一返回映射,多对多返回映射,自定义返回ResultType,引入后不会对原有的业务产生影响, 只拓展不修改

qq_31116181的博客 6万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

[特殊字符]【MyBatis-Plus 王者归来】MyBatis 的完美搭档!优雅 CRUD、高级特性与避坑指南 | 对比 MyBatis 更香!

MyBatis-Plus是MyBatis的增强工具,在不改变MyBatis核心功能的基础上提供更便捷的开发体验。本文通过对比MyBatis,介绍了MyBatis-Plus的核心优势:简化CRUD操作(通过BaseMapper接口)、强大的条件构造器、内置分页插件、逻辑删除等功能。文章以用户表操作为例,演示了如何从MyBatis项目升级到MyBatis-Plus,包括依赖引入、实体类注解优化(@TableName、@TableId)和Mapper接口改造(继承BaseMapper)。MyBatis-Plus大

WD1213484的博客 1206

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

mybatis升级为mybatis-plus踩到的坑

前言 最近使用RuoYi-Vue来做后台管理脚手架。RuoYi-Vue 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源。其官方文档如下 http://doc.ruoyi.vip/ 感兴趣的朋友,可以点链接查看。这个平台目前的orm框架是mybatis,而项目组的orm框架

kingwinstar的博客 5840

【Mybatis-plus】在mybatis-plus中 if test标签如何判断 list不为空

在 MyBatis-Plus 中,<if test="..."> 标签用于动态生成 SQL 语句。如果需要判断一个 List 是否不为空,可以使用以下方法:

No8g攻城狮的博客 2505

mybatis plus

mybatis的缺点: 1.mybatis sql工作量很大,尤其是字段多的时候。虽然说单表的增删改查操作可以通过mybatis generator工具来生成(或者自己写模板工具生成),但项目开发的过程中总免不了要新添加新字段,这些工具就帮不了我了,我得把新字段写到原来的所有增删改查的sql中。这是个痛苦的过程,特别是当你重复了很多次之后。 2.mybatis的单表操作也是贼麻烦的事,因为筛选的...

java开发郭靖 1万+

Mybatis-Plus和Mybatis区别

核心关系:MyBatis-Plus 是 MyBatis 的增强版,完全兼容 MyBatis,不改变原有使用方式,仅做功能补充。核心差异:MP 提供了「通用 CRUD、条件构造器、分页插件、代码生成器」等开箱即用的功能,大幅减少重复代码;而原生 MyBatis 更侧重 SQL 的手动控制。选型建议:优先选 MyBatis-Plus(开发效率更高),遇到复杂 SQL 时,仍可像原生 MyBatis 一样手动编写,兼顾效率与灵活性。

weixin_53050448的博客 1242

使用mybatis-plus遇到的坑

简介 如今的开发,对于数据库的curd,很多人都是使用mybatis,说到mybatis就不得不提mybatis的增强工具:mybatis-plus 。 mybatis的增强版,只做增强不做改变。博主大飞表示,如果你使用mybatis而不懂mybatis-plus,那你out了,五星推荐。 由来 最近老有人问我,在mybatis的使用中,通过下划线命名变量的总是不起作用。 今天就...

若释·飞语 2万+

关于mybatis-plus 和 mybatis-plus-boot-starter 异同点分析

在采用mybatis-plus做代码生成器时,我前面的文章https://blog.youkuaiyun.com/u012329294/article/details/90473681讲过,必须把其他的mybatis-plus删掉,只留下mybatis-plus-boot-starter。 但用mybatis-plus-boot-starter生成的代码,放在mybatis-plus依赖环境中, &l...

u012329294的专栏 2万+
上一篇: 基于 Sentinel 实现历史监控数据回看
下一篇: Spring Cache 缓存注解这样用,实在是太香了!
公众号-芋道源码
博客等级 码龄10年 1636粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值