flyway和jooq

在上文中,我推荐了flyway+jooq的组合。不同于我的其它推荐大多对标Google和FB这样的国际一线大厂,这个组合在国内也用的很多。不仅仅是一些创业公司(比如我前公司),诸如美团、58等很多大厂的新兴部门也会采用。
flyway,这个东西的理念平平无奇——做数据库的版本控制,但效果实际上出奇的好。DDL和DML的维护本身并不是一件复杂的事,常用的方法比如在项目中用一个sql文件记录,另开一个git仓库用来记录,都是可行的。在执行时,使用工单提交,完成线上变更。在我的实践经验中,这两种方法都有一些问题。
第一种,另开一个git仓库记录,它有一个致命的缺点使得这种方法是完全不可接受的,那就是数据库的版本和代码的版本被分开了。这样我获得一个代码版本之后,甚至无法方便的生产出一份对应的数据库来把代码跑起来,这种方式就被愉快的pass了。
第二种,在项目中用一个SQL文件来记录数据库结构,这种方法解决了上述问题,也就是说,我获得一个代码版本之后,直接用其中的SQL文件来创建数据库,即可把代码跑起来,这是代码和DDL统一管理的好处。但它也还是有缺点,那就是提交和执行的分离。1、我们在代码中保留的,通常是整个数据库的结构,包括建库语句和建表语句,而实际执行的,通常是一些变更语句,添加列之类的,这种不一致有时候会把问题弄复杂。2、工单执行的是不是就是项目中的文件中存储的,两者是否有出入,通常不太容易确定。据我观察过的很多个项目,test环境和prd环境的表结构肯定有不一样的,而且表还不少。这是代码和执行分离的坏处,需要建立统一的流程和工具来管理这件事。
flyway事实上就是做这件事的,不仅统一管理所有的DDL和DML,还支持使用flyway进行变更,解决了上述两个问题。同时flyway还有一些其它高级功能,大多数不怎么实用。总而言之,flyway其实就是一个非常简单的数据库版本控制工具。
说完了flyway,再说jooq,这个可就是重头戏了。jooq是我心目中最完美的数据库框架,没有之一,甚至于很难找出缺点。这个事情从头开始讲起,ORM框架,国外清一色的hibernate,国内清一色的mybatis。Hibernate是一个非常非常传统的ORM框架,而且做的是真正的ORM,中规中矩,在国外广泛使用,这不存在什么问题。国内就很奇怪了,mybatis是一个非常难用在我看来几乎没有什么优点的框架,使用复杂,类型不安全,更换数据库类型困难,连分页插件的实现方式都匪夷所思,国外几乎没有公司使用,在国内却广泛使用,究其原因,我总结了两点:1、大部分国内的技术栈是从阿里的技术栈演进来的,而阿里选择的是mybatis。2、阿里和很多其它公司使用mybatis还有另一个原因,mybatis的xml写法支持完全的自定义SQL,可以进行更方便的性能优化。
如果说,你的项目从一开始的定位就是并发量超高的诸如淘宝、支付宝或者秒杀系统,那么mybatis仍然是一个非常好的选型。但是可惜的是,绝大部分系统不是,也包括EA的所有系统。我们应当选择的是支持快速开发的框架,据我有限的知识,最常用的是两种,一种就是刚才说的,中规中矩的ORM框架,hibernate;而另外一种,就是“DSL风格数据库编程”,常用的框架有JPA+QueryDSL,再就是JOOQ,后来还出现了很多山寨版,比如基于mybatis的mybatis-plus。
这里面最好用的在我看来当然是jooq。先放一张图来展示jooq是怎么使用的:

任何你能想到的SQL,不管多复杂,几乎都能用jooq直接写出来。所有的表名、列名、where条件,关键词,全部都有编译器提示,全部都由编译器保证正确,绝对不会出现mybatis的xml里面的typo的情况发生。因此,用jooq几乎可以最大化的加速开发。除了开发上的优势以外,jooq是一个纯粹的类型安全的库,不存在任何类型不安全的转换,且提供了非常强大的扩展功能(比mybatis的插件系统强大的多)。与目前广泛使用的tkmybatis相比,tk不支持join,类型不安全,同时只能select *,不可同日而语。
跟mybatis本身比的话,其实主要就和上文《类型安全》说的一样了,mybatis依赖xml,而xml中写sql是没有编译器检查的,有时候写个if语句,就能把人恶心死,sql长了以后更是无法维护,有时候表名或者列名手抖打错了,可能自己还不知道,要跑一下才能发现。第一次写的时候的麻烦还是一时的,后续维护更加麻烦。假如要更换底层数据库,比如打算用h2来跑单元测试,由于mysql的sql非常不标准,使用mybatis写的mysql可以跑的语句h2很可能跑不了。上述问题,jooq就都不存在。相应的,带来的主要代价是,我们不能手写非常纯粹的sql了(事实上也可以,但是就没有mybatis方便了),所以无法写出性能达到极致的SQL(确实有SQL是用dsl很难写出来的),在性能上就差了。但是,几乎也就仅此而已,而这些性能上的差距,对绝大多数项目都是没有影响的。
最近经过测试,我发现在spring管理的事务之下,jooq和mybatis的可以混用的(主要就是两者的事务用的是同一个数据库连接),因此将jooq引入使用mybatis的项目,结合使用,可以提高开发效率。尽管,做同一件事用两种框架并不是一种好的行为,但在这件事情上,我视为特殊情况。jooq可以大幅加快SQL相关的工作的进行,视情况,如果进展顺利,希望最后能够替换mybatis。
参考资料:https://www.ershicimi.com/p/329ebece29bf4eba1bba551b2dd7a28a

发表评论

电子邮件地址不会被公开。 必填项已用*标注