1
头图
版本日期备注
1.02024.4.22文章首发
1.12024.10.12改进部分内容
本文内容已用一种抽象的方式做成了视频,喜欢看视频的同学可以在B站上搜索“抽象狗哥”观看相应的内容。

前阵子团队里有人提到了类似的问题,我自己先是顺手找了一圈,结果只找到了:https://github.com/xormplus/xorm。这个框架是基于xorm做的加强,但是在2020年就不维护了。显得很奇怪,明明是唯一一个支持了XML配置SQL的库,后面竟然凉了。

刚开始我是想不通的,但是仔细想了一下日常的开发习惯与一些历史原因,便想通了。

MyBatis火起来的原因

MyBatis是阿里推起来的,那时还叫IBatis,同期的竞争对手是Hibernate(基于JPA的标准实现)。按照JPA的标准来编程的确非常的方便,但是那个时代的数据库写SQL其实有很多特殊的技巧——无论是商业上获取巨大成功的Oracle和崭露头角的MySQL,因此会设置一个专门的岗位叫DBA(现在也有,但是供需量已经没有那个时候大了),DBA可以根据业务语义来做一些SQL的优化与建议,那么可以灵活自定义SQL的IBatis便成了当时极度流行的框架——并且SQL和代码隔离,负责优化SQL的同学可以直接对着XML一通改,改得好的话调用方都无感知。

另外一方面的原因则是早期的Hibernate实现有性能问题比如在delete 1024条数据时,会执行1024次delete。 这对于机械硬盘来说是难以接受的。

如果性能够的话,那么肯定是方便更重要啦!

随着开源数据库的发展——越来越多的商业公司选择白嫖开源,这让开源数据库遇到了更多场景和挑战。因此他们的SQL优化器也开始变得智能了起来。这个时候绝大多数业务上的增删改查都可以用一些简单的语句来满足,此时JPA就显得很舒服了,我们以Hibernate为例——MyBatis的配置文件与代码天然有割裂感。相信多写MyBatis XML的同学,对于那种偶尔的条件拼接错误、条件判断写错导致出现一些晦涩的runtime error是日常感到头疼的。本质上来说是因为XML中的SQL就是一堆字符串,它不具备一系列的对象信息以及编译期的推导、类型检测能力。但是基于Hibernate生成的对象却可以避免这一系列问题。

如果偶尔有一些复杂的SQL,那么Hibernate也是支持裸SQL去写的。因此到了这个阶段,如果没有历史包袱的程序员大多数都会去选择拥抱JPA,SpringData也是很香的,可以参考那时ZStack里对于JPA到的一些使用与实现的封装:https://github.com/zstackio/zstack/wiki/%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C#%E4%BB%8B%E7%BB%8D

而有历史包袱的则可以使用MyBatis-Plus,它的调用方式其实和SpringData的一些接口有些类似。有兴趣的同学可以查看https://github.com/baomidou/mybatis-plus

MyBatis-Plus的在2016年诞生的,ZStack也是在2015年诞生的。我认为这也算是开源数据库优化器进入成熟的一个标志性阶段吧。

大数据应用层的同学该何去何从?

前面提到,一些业务上简单的增删改查都可以用JPA的实现去做。但是分析型场景该怎么办呢?众所周知分析型的SQL可以写的很复杂。如果你的项目正在转Go,且要把一堆复杂的SQL迁移进项目,那么我的建议是:

  1. 检查你的模型是否合理。DM层的SQL一般不会太复杂。
  2. 如果是是查询数量较小数据量的宽表、中间表(可能考虑减少成本),那么建议用Java项目做一层转发。
  3. 如果出于成本考虑,连Java那层的转发也想省去,可以试试Go的Gen ORM——https://gorm.io/gen/sql_annotation.html 它虽然没法用XML配置,但可以通过注释代码的模式实现类似MyBatis中类似注解的实现。或试试不再维护的https://github.com/xormplus/xorm了。
后面我发现https://github.com/donnie4w/gdao,以及https://github.com/eatmoreapple/juice都可以满足xml配置的需求。

结论

MyBatis这种写Raw SQL的实现在方便程度上始终低于JPA这种面向对象的方式。早期MyBatis的流行是基于SQL调优复杂的情况之上的。当开源数据库的优化器足够智能时,JPA的方式可以满足大多数的SQL调用,而且SpringData,Hibernate也支持Raw SQL的编写,因此后来推崇Raw SQL为主的框架便不再流行了。


泊浮目
4.9k 声望1.3k 粉丝