【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 里面居然还埋在一坨业务逻辑呢?
  • 知道就好,生产别这么干!谨记!!!

在这里插入图片描述

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

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值