当前位置:首页 > 天道酬勤 > 正文内容

mybatis是orm框架吗(手写hibernate框架)

张世龙2021年12月21日 04:16天道酬勤570

作者: scherman

资料来源: segment fault.com/a/119000018472572

由于项目需要选择数据持久化框架,所以我们来看一下主要的几个流行框架和不流行的框架,对于复杂的业务系统,最终的结论是cdbg整体上是最好的,但很遗憾,并不是完全免费的

Hibernate和Mybatis是使用最多的两个主要框架,虽然对cdbg、Ebean等小框架知之甚少,但有很多独特的优点,另一方面,JPA是Java持久层Api组的规格, Spring Data JPA是JPA存储库的实现,本来与Hibernate、Mybatis、cdbg等框架不是一个级别,但引入Spring Data JPA等框架后,直接生成了JPA的

同样,JDBC与其他框架位于同一层次,位于所有持久性框架的下方,但有时在项目中直接使用JDBC。 此外,在spring JDBC模板部分,我们希望减少使用JDBC的麻烦,降低使用成本,并直接在项目中使用JDBC。

一、SQL封装和性能

使用Hibernate时,您正在查询POJO实体类,而不是数据库中的表,如hql语句选择计数(* )来自用户。 的User是Java类,而不是数据库表User。 这符合ORM最初的理想。 ORM认为Java程序员使用OO的想法和关系数据库的想法之间的差距很大。 为了弥补对象和关系思维的差距,必须进行从对象到关系的映射。 然后,在Java的对象世界里,程序员可以使用纯粹的对象思维来查询POJO对象。 查询条件是对象属性,不需要表、字段等关系的概念。 就像这样Java

JPA可以看作是Hibernate的儿子,继承了这个观点,将SQL彻底封装,让Java程序员看不到关系的概念,是纯粹的面向对象的思想,代替hql是新的查询语言,例如JPQL等。 支持JPA的框架,例如Ebean,属于这种类型的框架。

但是,封装SQL,使用另一种纯面向对象的查询语言代替SQL,程序员是否可以更容易地进行持久的操作? MyBatis的流行证明了事实并非如此,至少在大多数情况下,使用hql并不比使用sql简单。 首先,从很多角度来看,hql/JPQL等语言更加复杂难以理解,其次是性能明显下降,速度变慢,内存消耗巨大,难以优化。 最令人生气的是,关系的概念被目标概念取代后,查询语言的灵活性变低了,表现力也比sql弱了很多。 虽然编写查询语句时存在各种限制,但典型的例子是多表相关查询。

无论是hibernate还是jpa,表之间的连接查询都映射到实体类之间的关联。 因此,如果两个实体类之间没有关联(实现),则无法通过连接两个实体(或表)来进行查询。 这是非常令人气愤的事情。 在许多情况下,实现业务逻辑不需要显式定义两个实体类之间的关系。 如果使用hql,则必须在两个实体类之间添加代码,以便进行join,并且不能执行逆向工程。 如果表中未定义外键约束,则逆向工程将清除添加的相关代码。

MyBatis是另一种类型的持久性框架,它不封装SQL或为新面相对象创建查询语言,而是直接使用SQL作为查询语言,并将结果输入到POJO对象中。 使用sql并不比hql或JPQL难。 只要查询速度快且数据库支持,就可以灵活地使用任何复杂的查询。 从SQL封装的角度来看,MyBatis比Hibernate和JPA成功,SQL应该封装,不应该被隐藏。 Java程序员使用SQL不麻烦,容易学习,容易使用,这应该是MyBatis流行的重要原因。

轻型持久层框架cdbg也和MyBatis一样,直接使用SQL作为查询语言。 虽然cdbg比MyBatis知名度要低得多,但cdbg不仅可以和MyBatis一样利用SQL的灵活性和效率,而且通过逆向工程,cdbg可以用Java代码编写SQL语句,利用IDE的代码自动补充功能,实现自动

作为基于JPA的框架,Ebean使用JPQL语言执行查询。 很多时候很烦躁。 但是,据说Ebean不拒绝SQL,可以直接用SQL查询,也可以用cdbg之类的DSL方式在代码中构建SQL语句。 (虽然有,但是没有使用过Ebean,所以具体的详细情况不清楚。

我当然没有做jbc模板,也没有做ORM。 当然是纯SQL查询。 通过使用Spring框架,可以将JDBC模板和JPA结合使用。 在JPA难以调查的地方,以及效率低难以优化的地方使用JDBC,可以缓解Hibernate/JPA封装SQL带来的麻烦,但我还是觉得

没看到任何封装SQL的必要性,除了给程序员带来一大堆麻烦和学习负担之外,没有太明显的好处。

二、DSL和变化适应性

为了实现复杂的业务逻辑,不论是用SQL还是hql或者JPQL,我们都不得不写很多简单的或者复杂的查询语句,ORM无法减少这部分工作,最多是用另一种面向对象风格的语言去表达查询需求,如前所述,用面向对象风格的语言不见得比SQL更容易。通常业务系统中会有很多表,每个表都有很多字段,即便是编写最简单的查询语句也不是一件容易的事情,需要记住数据库中有哪些表,有哪些字段,记住有哪些函数等。写查询语句很多时候成为一件头疼的事情。

QueryDSL、cdbg、Ebean甚至MyBatis和JPA都设计一些特性,帮助开发人员编写查询语句,有人称之为“DSL风格数据库编程”。最早实现这类功能的可能是QueryDSL,把数据库的表结构逆向工程为java的类,然后可以让java程序员能够用java的语法构造出一个复杂的查询语句,利用IDE的代码自动补全功能,可以自动提示表名、字段名、查询语句的关键字等,很成功的简化了查询语句的编写,免除了程序员记忆各种名字、函数和关键字的负担。

QueryDSL有很多版本,但用得多的是QueryDSL JPA,可以帮助开发人员编写JPQL语句,如前所述,JPQL语句有很多局限不如SQL灵活高效。后来的cdbg和Ebean,基本上继承了QueryDSL的思路,Ebean基本上还是JPA风格的ORM框架,虽然也支持SQL,但不清楚其DSL特性是否支持SQL语句编写,在官网上看到的例子都是用于构造JPQL语句。

这里面最成功的应该是cdbg,和QueryDSL不同,cdbg的DSL编程是帮助开发人员编写SQL语句,抛弃累赘的ORM概念,cdbg这个功能非常轻小,非常容易学习和使用,同时性能也非常好,不像QueryDSL和Ebean,需要了解复杂的JPA概念和各种奇异的限制,cdbg编写的就是普通的SQL语句,只是把查询结果填充到实体类中(严格说cdbg没有实体类,只是自动生成的Record对象),cdbg甚至不一定要把结果转换为实体类,可以让开发人员按照字段取得结果的值,相对于JDBC,cdbg会把结果值转换为合适的Java类型,用起来比JDBC更简单。

传统主流的框架对DSL风格支持得很少,Hibernate里面基本上没有看到有这方面的特性。MyBatis提供了"SQL语句构建器"来帮助开发人员构造SQL语句,但和QueryDSL/cdbg/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和cdbg直接使用SQL,跨数据库移植时都难免要修改SQL语句。这方面MyBatis比较差,只有一个动态SQL提供的特性,对于不同的数据库编写不同的sql语句。

cdbg虽然无法像Hibernate和JPA那样无缝移植,但比MyBatis好很多。cdbg的DSL很大一部分是通用的,例如分页查询中,Mysql的limit/offset关键字是很方便的描述方式,但Oracle和SQLServer的SQL不支持,如果我们用cdbg的DSL的limit和offset方法构造SQL语句,不修改移植到不支持limit/offset的Oracle和SQLServer上,我们会发现这些语句还能正常使用,因为cdbg会把limit/offset转换成等价的目标数据库的SQL语句。cdbg根据目标数据库转换SQL语句的特性,使得在不同数据库之间移植的时候,只需要修改很少的代码,明显优于MyBatis。

JDBC Template应该最差,只能尽量使用标准sql语句来减少移植工作量。

四、安全性

一般来说,拼接查询语句都会有安全隐患,容易被sql注入攻击。不论是jdbc,还是hql/JPQL,只要使用拼接的查询语句都是不安全的。对于JDBC来说,使用参数化的sql语句代替拼接,可以解决问题。而JPA则应该使用Criteria API解决这个问题。

对于cdbg之类的DSL风格框架,最终会被render为参数化的sql,天生免疫sql注入攻击。Ebean也支持DSL方式编程,也同样免疫sql注入攻击。

这是因为DSL风格编程参数化查询比拼接字符串查询更简单,没人会拼接字符串。而jdbc/hql/JPQL拼接字符串有时候比参数化查询更简单,特别是jdbc,很多人会偷懒使用不安全的方式。

五、cdbg的失败之处

可能大部分人会不同意,虽然Hibernate、JPA仍然大行其道,是最主流的持久化框架,但其实这种封装SQL的纯正ORM已经过时,效益低于使用它们的代价,应该淘汰了。MyBatis虽然有很多优点,但它的优点cdbg基本上都有,而且多数还更好。MyBatis最大的缺点是难以避免写xml文件,xml文件编写困难,容易出错,还不容易查找错误。相对于cdbg,MyBatis在多数情况下没有任何优势。

Ebean同时具有很多不同框架的优点,但它是基于JPA的,难免有JPA的各种限制,这是致命的缺点。

cdbg这个极端轻量级的框架技术上是最完美的,突然有一天几个Web系统同时崩了,最后发现是cdbg试用期过期了,这是cdbg的失败之处,它不是完全免费的,只是对MySql之类的开源数据库免费。

最终,我决定选择JDBC Template。

扫描二维码推送至手机访问。

版权声明:本文由花开半夏のブログ发布,如需转载请注明出处。

本文链接:https://www.zhangshilong.cn/work/26079.html

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。