【Mybatis】Mybatis还能这么玩?整的我一脸懵逼。。。

开篇词:

这期给大家分享一个关于 MyBatis 的“编程小技巧”,说真的,这骚操作,直接整的我一脸懵逼。。。

干货篇:

按秒杀场景举例:

service层的代码肯定有如下逻辑
1.保存订单
2.更新库存

1.分分钟能写出这样的伪代码:

public void seckill() {
    //开启事务
    begin;
   1.保存订单
   service.save();
   2.更新库存
   service.update();
    if (checkIfSuccess()) {
        //提交事务
        commit;
    } else {
        //回滚事务
        rollback
    }
}

现在我给你展示一下用“编程小技巧”写出来的真实的代码。

2.别····眨····眼~~

这就是一个 MyBatis 的 mapper 接口,接下来就直接到了 mapper.xml 文件里面:

在这里插入图片描述

这写法,这小技巧,我都不打算问你骚不骚,我就问你见没见过?

在这里插入图片描述

3.关键是真能用吗?

秉承着大胆假设小心求证的态度,本地自测了一波~~
项目启动之后发起调用,控制台直接报了错:
在这里插入图片描述

看到这个报错的时候,我下意识的觉得就是 MyBatis 不支持这样的写法,直接报错了,这也符合我的预期

4.有意思的事情发生了

但是如果配置了如下属性
allowMultiQueries=true
无报错且正确执行了 insert 和 update!!!!
在这里插入图片描述

对于这个参数,查阅了官网:

Allow the use of “;” to delimit multiple queries during one statement. This option does not affect the ‘addBatch()’ and ‘executeBatch()’ methods, which rely on ‘rewriteBatchStatements’ instead.
允许在一条语句中使用"; "分隔多个查询。该选项不会影响 "addBatch() "和 "executeBatch() "方法,因为它们依赖于 “rewriteBatchStatements”。

在介绍 allowMultiQueries 的时候,还提到了一个

5.rewriteBatchStatements 参数。

关于这个参数,简单简单介绍一下:

  • rewriteBatchStatements 参数并不是直接关联于 MyBatis 的一个配置选项,但它经常与 JDBC 驱动(尤其是 MySQL JDBC 驱动)和 MyBatis 的批量操作一起被提及。这个参数实际上是 MySQL JDBC 驱动中的一个特性,用于优化批量插入(INSERT)、更新(UPDATE)和删除(DELETE)操作的性能。
  • MySQL JDBC 驱动的 rewriteBatchedStatements
    在 MySQL JDBC 驱动中,rewriteBatchedStatements 是一个连接字符串(URL)参数,用于启用或禁用对批量语句的重写。当设置为 true 时,MySQL JDBC 驱动会尝试将多个单独的 INSERT、UPDATE 或 DELETE 语句组合成一个批量语句发送给 MySQL 服务器,以减少网络往返次数和提高性能。这对于大量数据的批量操作特别有用。
  • 如何设置
    在 JDBC 连接字符串中设置 rewriteBatchedStatements=true。例如,如果你使用的是 MySQL 数据库,你的连接字符串可能看起来像这样:
java
复制代码
jdbc:mysql://localhost:3306/yourdatabase?rewriteBatchedStatements=true
MyBatis 与 rewriteBatchedStatements
  • 虽然 rewriteBatchedStatements 是 JDBC 驱动级别的配置,但 MyBatis 通过其底层使用的 JDBC 连接来利用这一特性。当你在 MyBatis 中执行批量操作时(比如使用 标签在 MyBatis 映射文件中构造多个 INSERT 语句,或者使用 MyBatis 的 SqlSession.insertList 方法等),如果 JDBC 连接字符串中启用了 rewriteBatchedStatements,那么 MyBatis 的这些批量操作就能更有效地执行。
  • 注意事项
    rewriteBatchedStatements 并不总是能完全优化所有类型的批量操作。它主要对 INSERT、UPDATE 和 DELETE 语句有效,而对于 SELECT 语句则没有直接影响。
  • 在某些情况下,使用 rewriteBatchedStatements 可能会导致性能下降,特别是在处理大量小事务时。因此,建议根据你的具体应用场景进行测试。
  • 启用 rewriteBatchedStatements 可能会改变 SQL 语句的发送方式,这可能会影响到一些基于 SQL 日志的监控工具或数据库审计工具的行为。

6.扩展

题外话,请问是“订单加一,库存减一”的性能好,还是“库存减一,订单加一”的性能好,还是说这二者没有什么区别?

  • 首先,从执行结果上看,这二者确实是没有什么区别的,都能保证业务场景的正确性。
  • 但是当你考虑性能的时候,肯定是“订单加一,库存减一”的性能更好。
  • 因为 where 条件中是 id=1,所以锁是加在唯一索引上的,而且表中存在该记录,所以只会对 id=1 这行记录加锁。
    针对 id=1 这一个产品来说,如果它是一个热点商品,我们采取“订单加一,库存减一”的写法,性能会更高一点。

在加锁频率相同的情况下,解锁越快的,性能越高。
上个图你就明白了:
在这里插入图片描述

总结篇:

  • 首先这样的写法就不符合绝大部分程序员的认知。
  • 谁能想到mapper.xml 里面居然还埋在一坨业务逻辑呢?
  • 知道就好,生产别这么干!谨记!!!

在这里插入图片描述

我是杰叔叔,一名沪漂的码农,下期再会!

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 17:10:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 17:10:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 17:10:01       58 阅读
  4. Python语言-面向对象

    2024-07-18 17:10:01       69 阅读

热门阅读

  1. 02-Redis未授权访问漏洞

    2024-07-18 17:10:01       21 阅读
  2. 开发一个商城app需要多少钱

    2024-07-18 17:10:01       21 阅读
  3. 【STM32】超声波一般常用哪两个引脚?

    2024-07-18 17:10:01       19 阅读
  4. Linux 之 ln 硬链接和软链接

    2024-07-18 17:10:01       20 阅读
  5. spfa判断负环

    2024-07-18 17:10:01       24 阅读
  6. 如何建设和维护数据仓库:深入指南

    2024-07-18 17:10:01       24 阅读
  7. vue程序中如何设置调用springboot服务的url

    2024-07-18 17:10:01       23 阅读
  8. CCF-CSP认证考试 202406-3 文本分词 100分题解

    2024-07-18 17:10:01       20 阅读
  9. 代码注释中的常见标记

    2024-07-18 17:10:01       22 阅读
  10. 2024.7.17 ABAP面试题目总结

    2024-07-18 17:10:01       24 阅读
  11. 【笔记-Python】内置容器-list

    2024-07-18 17:10:01       19 阅读
  12. 每日一题——第十四题

    2024-07-18 17:10:01       23 阅读