我觉得为啥这么多人都说Mybatis好,原因最主要是Mybatis容易上手,现在学编程学数据库基本都学过SQL,Mybatis面向DB基于SQL的模式相对来说就显得特别直观友好。
而JPA是基于ORM的,把代码和DB分离,相当于在代码和DB之间增加了一个新的层面,一套新的标准,去间接操作DB,相对SQL的模式来说就显得不够直接和易于控制,增加了学习成本,碰到这样那样问题的时候,很容易让人放弃。
特别是在团队开发的时候,你很难掌控每个人对JPA的深层机制的理解程度,为了避免木桶效应,还不如干脆都用Mybatis。其实这两者就功能的角度来说,肯定是相互学习借鉴的,Spring Data JPA也可以执行原生SQL,存储过程,Mybatis也有一部分ORM特性,选择Spring Data JPA还是选择Mybatis都不会影响到最终业务逻辑的实现。不影响业务实现的前提下,选型主要就是选择开发和维护时的效率了。
这方面的话我觉得在开发阶段频繁修改表结构时Mybatis不如Spring Data JPA或者说Hibernate的正向工程方便快捷,再考虑和spring全家桶的版本兼容性,我们团队最终选了Spring Data JPA。
我们团队早期一些项目使用的是 MyBatis,后续所有项目都换用 Spring Data JPA 了。因为在早期使用 Spring Data JPA 时,就解决掉了它最大的痛点,也就是大家经常说的不能应对复杂业务场景、不便于写复杂动态 SQL 的问题。
我写了一个 Spring Data JPA 扩展库 Fenix,能完全兼容 Spring Data JPA,可以认为是 JPA 界的 JPA Plus。该扩展库早期的目的就是为了解决复杂动态 SQL 而生的,后来也陆续扩展了更多的功能,比如提供了更高效的批量增删改的一些方法,返回自定义 JavaBean,非 null 属性的增量更新等等。
所以,你也可以像 MyBatis 那样将复杂的 JPQL (或者原生 SQL) 语句写在 XML 里面,XML 方式的本质上是让 SQL 和 Java 代码解耦,易于单独维护和管理 SQL。为了增加 SQL 语句的动态性,也可以写 #{} 表达式、if/else、foreach 等过程式的逻辑控制语法。针对常见的动态 SQL 片段,还内置引入了大量常见的 XML SQL 语义化标签,相比 MyBatis 中纯 if/else、foreach 的一些动态标签代码可读性更高、也能达到更极致的可复用性。除了支持 XML 形式的动态 JPQL (或 SQL) 写法之外,还有三种其他方式来写查询语句,分别是:基于 JPQL(或SQL) 的 Java 链式 API 方式、基于 Specification 的 Java API 方式和 JavaBean (VO) 注解的方式。后面这两种由于是基于 Specification 方式的,甚至都不用在 Repository 接口中写任何方法。
选择 Spring Data JPA 的核心原因有以下几点:
-
从根本上来说是开发模式的转变,新项目不用事先就设计好完整的数据库和表结构,开发过程中自动生成数据库表结构,可以快速开发和迭代,逐渐完善。
-
在企业级项目中,能享受到跨数据库类型的好处,能屏蔽底层数据库的一些 SQL 差异。不同地区的客户可能会要求指定使用某种特定的数据库,也就几乎没有多少改造的成本了。
-
持久层的代码量更少,维护起来更加简单,后续新增、修改字段时,大多数时候只需要维护 Java Entity 的注解映射关系就行了。
由于解决了 Spring Data JPA 的不便于写复杂动态 SQL 的问题,它剩下的最大缺点就是复杂性高的问题了,因为其基于 Hibernate,封装度很高,学习成本也自然更高。而且相关的资料、博客比 MyBatis 而言也少很多,MyBatis 可是从很早就是有官方中文文档的,而 Spring Data JPA 的官方文档介绍的内容太简单,只能应对一些简单的业务场景,复杂场景、高级功能介绍太少。这也劝退了不少的人。所以,我经常能听到一些初学者问,JPA 中能不能写多表查询之类的问题。
还有,在 JPA 中不建议使用 Entity 实体对象间的一对多、多对多之类的功能,也就是说 Entity 之间尽量独立,要关联查询时,通过 JPQL 或者 SQL 查询或更新就行,避免一些级联关系之间的隐式操作,代码含义更透明,方便应对后续的扩展或针对性的优化改造。
网友评论