作者:scherman\
起源:https://segmentfault.com/a/11…
因为我的项目须要抉择数据长久化框架,看了一下次要几个风行的和不风行的框架,对于简单业务零碎,最终的论断是,JOOQ是总体上最好的,惋惜不是完全免费,最终抉择JDBC Template。
Hibernate和Mybatis是应用最多的两个支流框架,而JOOQ、Ebean等小众框架则晓得的人不多,但也有很多独特的长处;而JPA则是一组Java长久层Api的标准,Spring Data JPA是JPA Repository的实现,原本和Hibernate、Mybatis、JOOQ之类的框架不在同一个档次上,但引入Spring Data JPA之类框架之后,咱们会间接应用JPA的API查问更新数据库,就像咱们应用Mybatis一样,所以这里也把JPA和其余框架放在一起进行比拟。
同样,JDBC和其余框架也在同一档次,位于所有长久框架的底层,但咱们有时候也会间接在我的项目中应用JDBC,而Spring JDBC Template局部打消了应用JDBC的繁琐细节,升高了应用老本,使得咱们更加违心在我的项目中间接应用JDBC。
一、SQL封装和性能
在应用Hibernate的时候,咱们查问的是POJO实体类,而不再是数据库的表,例如hql语句 select count(*) from User,外面的User是一个Java类,而不是数据库表User。这合乎ORM最后的现实,ORM认为Java程序员应用OO的思维形式,和关系数据库的思维形式差距微小,为了填补对象和关系思维形式的鸿沟,必须做一个对象到关系的映射,而后在Java的对象世界中,程序员能够应用纯的对象的思维形式,查问POJO对象,查问条件是对象属性,不再须要有任何表、字段等关系的概念,这样java程序员就更容易做长久层的操作。
JPA能够视为Hibernate的儿子,也继承了这个思路,把SQL彻底封装起来,让Java程序员看不到关系的概念,用纯的面向对象思维,从新发明一个新的查询语言代替sql,比方hql,还有JPQL等。反对JPA的框架,例如Ebean都属于这种类型的框架。
但封装SQL,应用另一种纯的面向对象查询语言代替sql,真的可能让程序员更容易实现长久层操作吗?MyBatis的风行证实了事实并非如此,至多在大多数状况下,应用hql并不比应用sql简略。首先,从很多角度上看,hql/JPQL等语言更加简单和难以了解;其次就是性能上明显降低,速度更慢,内存占用微小,而且还不好优化。最为恼火的是,当关系的概念被替换为对象的概念之后,查询语言的灵活性变得很差,表达能力也比sql弱很多。写查问语句的时候受到各种各样的限度,一个典型的例子就是多表关联查问。
不论是hibernate还是jpa,表之间的连贯查问,被映射为实体类之间的关联关系,这样,如果两个实体类之间没有(实现)关联关系,你就不能把两个实体(或者表)join起来查问。这是很恼火的事件,因为咱们很多时候并不需要显式定义两个实体类之间的关联关系就能够实现业务逻辑,如果应用hql,只是为了join咱们就必须在两个实体类之间增加代码,而且还不能逆向工程,如果表外面没有定义外键束缚的话,逆向工程会把咱们增加的关联代码抹掉。
MyBatis则是另外一种类型的长久化框架,它没有封装SQL也没有创立一种新的面相对象的查询语言,而是间接应用SQL作为查询语言,只是把后果填入POJO对象而已。应用sql并不比hql和JPQL艰难,查问速度快,能够灵便应用任意简单的查问只有数据库反对。从SQL封装角度上看,MyBatis比Hibernate和JPA胜利,SQL本不该被封装和暗藏,让Java程序员应用SQL既不麻烦也更容易学习和上手,这应该是MyBatis流行起来的重要起因。
轻量级长久层框架JOOQ也和MyBatis一样,间接应用SQL作为查询语言,比起MyBatis,JOOQ尽管知名度要低得多,但JOOQ岂但和MyBatis一样能够利用SQL的灵活性和高效率,通过逆向工程,JOOQ还能够用Java代码来编写SQL语句,利用IDE的代码主动补全性能,主动提醒表名和字段名,缩小程序员记忆负担,还能够在元数据发生变化时产生编译谬误,提醒程序员批改相应的SQL语句。
Ebean作为一种基于JPA的框架,它也应用JPQL语言进行查问,少数状况下会让人很恼火。但据说Ebean不排挤SQL,能够间接用SQL查问,也能够用相似JOOQ的DSL形式在代码中结构SQL语句(还是JPQL语句?),但没用过Ebean,所以具体细节不分明。
JDBC Template就不用说了,它基本没做ORM,当然是纯SQL查问。利用Spring框架,能够把JDBC Template和JPA联合起来应用,在JPA不好查问的中央,或者效率低不好优化的中央应用JDBC,缓解了Hibernate/JPA封装SQL造成的麻烦,但我仍没看到任何封装SQL的必要性,除了给程序员带来一大堆麻烦和学习累赘之外,没有太显著的益处。
二、DSL和变动适应性
为了实现简单的业务逻辑,不论是用SQL还是hql或者JPQL,咱们都不得不写很多简略的或者简单的查问语句,ORM无奈缩小这部分工作,最多是用另一种面向对象格调的语言去表白查问需要,如前所述,用面向对象格调的语言不见得比SQL更容易。通常业务零碎中会有很多表,每个表都有很多字段,即使是编写最简略的查问语句也不是一件容易的事件,须要记住数据库中有哪些表,有哪些字段,记住有哪些函数等。写查问语句很多时候成为一件头疼的事件。
QueryDSL、JOOQ、Ebean甚至MyBatis和JPA都设计一些个性,帮忙开发人员编写查问语句,有人称之为“DSL格调数据库编程”。最早实现这类性能的可能是QueryDSL,把数据库的表构造逆向工程为java的类,而后能够让java程序员可能用java的语法结构出一个简单的查问语句,利用IDE的代码主动补全性能,能够主动提醒表名、字段名、查问语句的关键字等,很胜利的简化了查问语句的编写,罢黜了程序员记忆各种名字、函数和关键字的累赘。
QueryDSL有很多版本,但用得多的是QueryDSL JPA,能够帮忙开发人员编写JPQL语句,如前所述,JPQL语句有很多局限不如SQL灵便高效。起初的JOOQ和Ebean,基本上继承了QueryDSL的思路,Ebean基本上还是JPA格调的ORM框架,尽管也反对SQL,但不分明其DSL个性是否反对SQL语句编写,在官网上看到的例子都是用于结构JPQL语句。
这外面最胜利的应该是JOOQ,和QueryDSL不同,JOOQ的DSL编程是帮忙开发人员编写SQL语句,摈弃累赘的ORM概念,JOOQ这个性能十分轻小,非常容易学习和应用,同时性能也十分好,不像QueryDSL和Ebean,须要理解简单的JPA概念和各种奇怪的限度,JOOQ编写的就是一般的SQL语句,只是把查问后果填充到实体类中(严格说JOOQ没有实体类,只是主动生成的Record对象),JOOQ甚至不肯定要把后果转换为实体类,能够让开发人员依照字段获得后果的值,绝对于JDBC,JOOQ会把后果值转换为适合的Java类型,用起来比JDBC更简略。
传统支流的框架对DSL格调反对得很少,Hibernate外面基本上没有看到有这方面的个性。MyBatis提供了”SQL语句构建器”来帮忙开发人员结构SQL语句,但和QueryDSL/JOOQ/Ebean差很多,不能提醒表名和字段名,语法也显得累赘不像SQL。
JPA给人的印象是简单难懂,它的MetaModel Api继承了特点,MetaModel API+Criteria API,再配合Hibernate JPA 2 Metamodel Generator,让人有点QueryDSL JPA的感觉,只是绕了一个大大的弯,叠加了好几层技术,最初勉强实现了QueryDSL JPA的简略易懂的性能。很多人不举荐JPA+QueryDSL的用法,而是举荐JPA MetaModel API+Criteria API+Hibernate JPA 2 Metamodel Generator的用法,让人很难了解,兴许是因为这个计划是纯的规范的JPA计划。
数据库DSL编程的另一个次要卖点是变动适应性强,数据库表构造在开发过程中通常会频繁发生变化,传统的非DSL编程,字段名只是一个字符串,如果字段名或者类型扭转之后,查问语句没有相应批改,编译不会出错,也容易被开发人员疏忽,是bug的一个次要起源。DSL编程外面,字段被逆向工程为一个java类的属性,数据库构造扭转之后,作为java代码一部分的查问语句会产生编译谬误,提醒开发人员进行批改,能够缩小大量bug,加重测试的累赘,进步软件的可靠性和品质。
三、跨数据库移植
Hibernate和JPA应用hql和JPQL这类数据库无关的两头语言形容查问,能够在不同数据库中无缝移植,移植到一个SQL有微小差异的数据库通常不须要批改代码或者只须要批改很少的代码。Ebean如果不应用原生SQL,而是应用JPA的形式开发,也能在不同数据库中平滑的移植。
MyBatis和JOOQ间接应用SQL,跨数据库移植时都不免要批改SQL语句。这方面MyBatis比拟差,只有一个动静SQL提供的个性,对于不同的数据库编写不同的sql语句。
JOOQ尽管无奈像Hibernate和JPA那样无缝移植,但比MyBatis好很多。JOOQ的DSL很大一部分是通用的,例如分页查问中,Mysql的limit/offset关键字是很不便的形容形式,但Oracle和SQLServer的SQL不反对,如果咱们用JOOQ的DSL的limit和offset办法结构SQL语句,不批改移植到不反对limit/offset的Oracle和SQLServer上,咱们会发现这些语句还能失常应用,因为JOOQ会把limit/offset转换成等价的指标数据库的SQL语句。JOOQ依据指标数据库转换SQL语句的个性,使得在不同数据库之间移植的时候,只须要批改很少的代码,显著优于MyBatis。
JDBC Template应该最差,只能尽量应用规范sql语句来缩小移植工作量。
四、安全性
一般来说,拼接查问语句都会有安全隐患,容易被sql注入攻打。不论是jdbc,还是hql/JPQL,只有应用拼接的查问语句都是不平安的。对于JDBC来说,应用参数化的sql语句代替拼接,能够解决问题。而JPA则应该应用Criteria API解决这个问题。
对于JOOQ之类的DSL格调框架,最终会被render为参数化的sql,天生免疫sql注入攻打。Ebean也反对DSL形式编程,也同样免疫sql注入攻打。
这是因为DSL格调编程参数化查问比拼接字符串查问更简略,没人会拼接字符串。而jdbc/hql/JPQL拼接字符串有时候比参数化查问更简略,特地是jdbc,很多人会偷懒应用不平安的形式。
五、JOOQ的失败之处
可能大部分人会不批准,尽管Hibernate、JPA依然大行其道,是最支流的长久化框架,但其实这种封装SQL的纯正ORM曾经过期,效益低于应用它们的代价,应该淘汰了。MyBatis尽管有很多长处,但它的长处JOOQ基本上都有,而且少数还更好。MyBatis最大的毛病是难以避免写xml文件,xml文件编写艰难,容易出错,还不容易查找谬误。绝对于JOOQ,MyBatis在少数状况下没有任何劣势。
Ebean同时具备很多不同框架的长处,但它是基于JPA的,不免有JPA的各种限度,这是致命的毛病。
JOOQ这个极其轻量级的框架技术上是最完满的,忽然有一天几个Web零碎同时崩了,最初发现是JOOQ试用期过期了,这是JOOQ的失败之处,它不是完全免费的,只是对MySql之类的开源数据库收费。
最终,我决定抉择JDBC Template。
近期热文举荐:
1.1,000+ 道 Java面试题及答案整顿(2021最新版)
2.别在再满屏的 if/ else 了,试试策略模式,真香!!
3.卧槽!Java 中的 xx ≠ null 是什么新语法?
4.Spring Boot 2.5 重磅公布,光明模式太炸了!
5.《Java开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞+转发哦!