思考:为啥 Go 里没有类似 MyBatis 支持 XML 配置 SQL 的框架
本文首发于 2024.4.22
前阵子团队里有个老服务的迁移语言任务,这个服务是类似于一个 OneService 的实现,要从 Java 转到 Go。有人提了这样的问题,我自己先是顺手找了一圈,结果只找到了:https://github.com/xormplus/xorm。这个框架是基于 xorm 做的加强,但是在 2020 年就不维护了。显得很奇怪,明明是唯一一个支持了 XML 配置 SQL 的库,后面竟然凉了。
说句题外话——在没有具体上下文的情况下,讨论一些绝对的对错没有什么意义。举个例子,说谎是对的吗?一般人第一个反应是错的。那善意的谎言呢?是不是对的。
同样的,去除上下文,只听“XML 写 SQL 在 Go 里的实现”,大多数人都会觉得很恶心。那补充一个上下文,XML 里面都是基于宽表的分析型复杂语句,大家还愿意写在代码里耦着吗?再补充个上下文,它是一个存在已久的服务,里面有上千个 SQL 配置着,用来做 OneService 的服务。不找这样的实现,谁来负责迁移呢?迁移以后,出事了算谁的呢?
刚开始我是想不通的,但是仔细想了一下日常的开发习惯与一些历史原因,便想通了。
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/数据库操作#介绍
而有历史包袱的则可以使用 MyBatis-Plus,它的调用方式其实和 SpringData 的一些接口有些类似。有兴趣的同学可以查看https://github.com/baomidou/mybatis-plus。
MyBatis-Plus 的在 2016 年诞生的,ZStack 也是在 2015 年诞生的。我认为这也算是开源数据库优化器进入成熟的一个标志性阶段吧。
大数据应用层的同学该何去何从?
前面提到,一些业务上简单的增删改查都可以用 JPA 的实现去做。但是分析型场景该怎么办呢?众所周知分析型的 SQL 可以写的很复杂。如果你的项目正在转 Go,且要把一堆复杂的 SQL 迁移进项目,那么我的建议是:
检查你的模型是否合理。DM 层的 SQL 一般不会太复杂。
如果是是查询数量较小数据量的宽表、中间表(可能考虑减少成本),那么建议用 Java 项目做一层转发。
如果出于成本考虑,连 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 为主的框架便不再流行了。
版权声明: 本文为 InfoQ 作者【泊浮目】的原创文章。
原文链接:【http://xie.infoq.cn/article/2a9dc1154d1b34f04f7976f11】。文章转载请联系作者。







评论