diagnostics
1 天前
数据库访问一般就是两个门派:
- JPA 、Hibernate 等 ORM:这类就是解决大部分 CRUD 需求的,简单的查询,涉及到多表,复杂查询就会性能低下,上手门槛也更高
- JDBC Temple 、MyBatis 、JOOQ 这类 SQL Helper:这类就是解决复杂查询的,因为本来就是 SQL ,想咋写就咋写
因为本来就是 SQL ,因此先说说第二类的发展历程,一开始大家写 JDBC 还好,写多了发现模板代码太多了,主要是两个层面,一个是连接这边的代码,一个是 ResultSet 做数据转换的代码,所以诞生了类似于 Apache Commons DbUtils 这种工具来简化,在 Spring 环境中则是 Spring JdbcTemplate 。
接下来事情就会朝着两极发展,还是先从 SQL 说起
Commons DbUtils 、JdbcTemplate 这类框架只简化了连接和响应映射,在动态 SQL 的支持比较少,因此诞生了 MyBatis 也就是 JdbcTemplate 高级版,通过模板引擎解决动态 SQL ,并且支持预定义的一些 SQL
当然 Mybatis 被人诟病的 XML ,还有动态能力在复杂场景还是有限的,例如写一个递归形式的动态条件(再举个例子,DAO 方法只穿入一个 filter ,这个 filter 可以是普通的 KeyValue 过滤,也可以多个 KV 组成的 AnyOf 和 AllOf 多重过滤,后两者对应的就是 id in (select id from t where f1 and/or f2 and/or f3...),这里面还可以动态拼接,我认为这种在 Java 里要用多态和类型匹配去做,MyBatis 对这个支持就不太行)
讲完了问题,就引出解决 MyBatis 这个陈旧框架的升级版 JOOQ ,这里用 TypeSafe 的 API 来编写复杂 SQL ,一来不需要频繁和 SQL 直接交互( Mybatis 也有一些这种痛点),也能避免出错;二来动态能力增强了,我能在 Java 代码而不是 XML 了编写内容。
到这里就是 SQL 帮助类这一方向发展的极端了(如果有更好的框架,可以提出),这里没有提到其他帖子的注入 MyBatis Plus (Join ),tk mybatis 等增强,而是因为他们要做的事情和 JPA 类似。
接下来谈谈 JPA ,JPA 的诞生我认为是解决 Commons DbUtils 、JdbcTemplate 这类框架中,对于一个表应该有的大部分普通操作 CRUD 没有预定义好一些模板代码,导致用户又需要频繁去写 findById ,findAll ,findCountByXXX 等操作(如果直接用 MyBatis ,也有这个问题,因此没有一个方案是一劳永逸的),简单来说我认为 JPA 就是用面向对象的方式编写简单查询,然后无感生成对应的模板 SQL 。但是这里的问题在于,JPA 这种注解时,方法名编写查询的方式,注定写不了复杂 SQL ,这又是一个新的问题。
总结,合并,从整个历程来看,数据库访问技术里,最终是趋向两个方向:简单查询自动生成、复杂 SQL 查询代码动态化,一个是前期需求,一个是后期需求。
以 MyBatis 和 JPA 举例,这两个框架都诞生了融合二者的三方框架:
- MyBatis Plus/ Mybatis Plus Join/ tk.mybatis
- JPA Criteria API, JPA QueryDSL
JPA/Hibernate 不能替代 SQL 。您应该充分利用 JPA 和 SQL ,并将它们组合成一个成功的解决方案。
MyBatis + 自动生成类增强插件似乎可行,但 MyBatis 自身的 SQL 能力不够强力,加上生成框架大部分就是国人写的,我并不是说国人的技术能力不行,而是国内这个职场氛围和文化,诞生不出来好的框架,原因有很多:996 、35 毕业、生存压力(投放广告),相对于 QueryDSL 、JOOQ 而言,国内的插件生态,文档不完善,功能不丰富。。。