持久层框架JPA与Mybatis该如何选型?这是我的观点欢迎指正

持久层框架JPA与Mybatis该如何选型?这是我的观点欢迎指正

一、现状描述

目前java 持久层ORM框架应用最广泛的就是JPA和Mybatis。关于二者的简介就不多说了。直接进入正题,每当有帖子比较这两个框架的选型及优缺点,就引来一场论战。从笔者的角度,为什么国内的开发团队较少使用JPA?为了避免开头就被抨击,我去国内某度指数获得如下数据,这个数据骗不了人。

持久层框架JPA与Mybatis该如何选型?这是我的观点欢迎指正

图中蓝色线条为Mybatis搜索量,绿色为JPA搜索量。如果你换一个国外的某趋势指数,你会得到一个完全不同的结果。那么这是为什么呢?我们还要从JPA的特点说起:

  • JPA对于单表的或者简单的SQL查询非常友好,甚至可以说非常智能。他为你准备好了大量的拿来即用的持久层操作方法。甚至只要写findByName这样一个接口方法,他就能智能的帮你执行根据名称查找实体类对应的表数据,完全不用写SQL。

  • 但是,JPA对于多表关联查询以及动态SQL、自定义SQL等非常不友好。对于JPA来说,一种实现方式是QueryDSL,实现的代码是下面这样的。你希望用这样的代码代替SQL么?

持久层框架JPA与Mybatis该如何选型?这是我的观点欢迎指正

另一种方法是使用NativeQuery,你希望在java代码里面用拼字符串的方式写SQL么?

持久层框架JPA与Mybatis该如何选型?这是我的观点欢迎指正

以上的这部分实现还没有考虑到动态SQL的问题,如果考虑到动态SQL,写法会更复杂。所谓的动态SQL就是:根据传入参数条件的不同,构造不同的SQL。很多的比较这两个框架的文章都忽略了动态SQL的问题,这方面Mybatis支持的更好。Mybatis写的动态SQL说到底还是SQL,而不是java代码或者java代码拼字符串。程序员特别排斥几件事:

  • 将复杂关联关系的SQL写在java代码里面,拼串书写不方便

  • SQL是最能表达实体关系查询的语言,程序员不希望使用异化SQL语言。

  • 程序员不希望学习不通用的东西,显然SQL大家都会

  • JPA虽然将大部分操作封装起来了,也挺好用的,但是SQL调优怎么做?

二、劣币驱逐良币?

持久层框架JPA与Mybatis该如何选型?这是我的观点欢迎指正

另外有一派观点,你看人家国外的程序员怎么都用JPA?你不去学习新东西,还不让别人用?JPA使用很方便啊,唯一缺点就是复杂关联SQL支持差一点,也还不错啊,你们这是劣币驱逐良币。如果经过很好的实体关系模型的设计,JPA显然是最优解,程序员写的SQL还真不如JPA的SQL有效率。笔者要说,这种观点也是有道理的。但是,笔者要说并不认为国内程序员不愿意学习,而是另有原因:

  • 笔者经常从事远程工作,与国外程序员接触较多。他们习惯使用JPA的一个原因,真的是因为他们所在区域的应用规模太小了,比起国内的一个应用动则上百万的用户相比,他们在数据库设计与调优的需求上更从容。

  • 国外的应用设计往往更简洁,而国内的应用需求往往功能性更强。如果不信,你可以去看看工作流,什么会签、流程回退什么的都是我们发明的,他们没有。你让他们用JPA写一个我们的工作流应用试一试,他们一样累吐血。

  • 异化SQL或者代码里面写SQL,一定程度上增加了学习成本和使用成本。所以用的人少,用的人少你就得迁就团队中的大部分人。

Mybatis的易用性也在不断改善,Mybatis-plus或者代码自动生成来弥补易用性上的不足,查询结果映射关系现在也都不用手写了。

JPA的身材、家室、性格样样都是满分,就是脸长得磕碜点难以处理社交关系。Mybatis虽说在各方面都不拔尖,身材还可以、样貌也还说得过去、性格也还好。关键是你说什么都听你的,还有愿意帮他化妆的朋友。要你说你选哪一个?

那么,在国外是如何开发大型互联网应用的呢?使用JPA会写复杂关联查询SQL么?答案是很少会用到,甚至有的公司就明令禁止写关联查询SQL。那怎么办?不用关联SQL怎么开发业务需求?不会啊。

三、服务拆分或微服务

持久层框架JPA与Mybatis该如何选型?这是我的观点欢迎指正

国内现在也有越来越多的公司,进行微服务的落地,然而真正落地比较好的企业少之又少。这和多表关联查询有什么关系?我们先来实现这样一个需求:查询属于A角色相关的所有的业务B数据。

  • 如果我们开发的是传统的单体应用,我们可能是把角色表A和业务表B进行关联查询,然后得到查询结果

  • 如果我们做的是微服务,我们可能是拆分为权限服务A、业务服务B。先去访问A服务接口获取角色标志信息,然后再根据角色标志信息去业务服务B接口获取业务数据。每个服务接口基本都是单表SQL。

那么有的人会说,访问两个接口一定比访问一个接口更慢吧!这个真的不是,如果我们做微服务,一定是我们的应用规模及数据量到达了一定程度。也一定会考虑分表分库、负载均衡、服务拆分细化等问题。当分布式的开发方式被应用越多,多表关联查询使用的机会也就越少。拆分后的服务由于功能单一、负载分流等原因,访问速度往往比大数据量数据集中存储、多服务集中部署的应用会快很多。

四、框架对比选型

总结一下笔者的观点:

  • 如果你是自己开发“小而美”的应用,建议你使用JPA

  • 如果你是开发业务型应用(比如银行、电信行业应用),当然要遵从团队的技术选型。这个技术选型通常是Mybatis。

  • 如果你们公司的管理非常规范,微服务落地经验也非常成熟,可以考虑在团队项目中使用JPA。少用或不用关联查询。

以上也仅是笔者自己的看法,欢迎指正!

期待您的关注

推荐:SpringBoot系列精品文章(16章97节), http://springboot.zimug.com

本号只做持续的知识输出,希望您能关注、评论、转发!您的支持是我不竭的创作动力!让知识产生价值、让程序员改变世界!