谈谈JPA与Mybatis

1,907 阅读5分钟

项目里用过JPA,当然更多的是用Mybatis。当时用JPA的时候是我强烈推荐使用的,才尝试使用一下,感觉还是可以的,比如项目启动自动建表更新表,更改对象即更改数据,关联查询,可以通过查询方法定义查询条件和排序。开发起来确实方便,但就和好多人说地那样,一定要搞清楚模型之间的关系,一对多,还是多对多等。

Mybatis 介绍

在Mybatis官方文档上,第一页就介绍了什么是Mybatis,我们来引用一下:

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

啥意思?简单来说是他只管输入和输出,SQL不管。SQL需要使用者自己写。

优点:

  • 灵活,可随意定义长SQL,短SQL,各种参数传入
  • 上手快,只要会写SQL,就会用

缺点:

  • 简单SQL也要我们手写

  • 分页也要手写

  • 主键需要自己塞值比如UUID

    等等太多了,说实话Mybatis帮我们做的事太少了。所以才会有PageHelper,MybatisPlus等。

JPA 介绍

JPA其实是一种规范,他不是具体的实现,全称 Java Persistence API,所以他有好多特性。Hibernate是实现了这个规范。我们现在都用的是Spring Data JPA,我们来罗列下他的特性:

  • 自动DDL,生成相关联的表
  • 自动SQL,继承接口一些单表的插入、更新、删除更方便
  • 面对对象的关联查询(级联),可以定义一多一,一对多,多对多
  • 级联更新
  • 通过方法名称定义查询(findByxxx),也是约定大于配置的一种吧
  • 多种主键支持
  • 分页支持
  • Querydsl
  • @Query 注解自定义查询

看看Spring Data JPA实现的东西不少,给我们开发提供了不少便捷。但既然是规范,就有约束,有约束就感觉不爽。比如:

  • 关联查询,我也不是每个语句都需要关联查询的,如果大批量的列表查询会浪费性能,有时候还会触发二级级联、三级级联,我们都知道他有N+1的问题,这样是大大浪费性能的。
  • 通过自定义方法查询(findByxxx),这种方式确实快,不需要写SQL,但有个问题,我们前端没传或传的是null或空串,只能表示查全部,而不是用null去查询
  • 更新,虽然更新对象即更新数据库,看似方便,但只能全表更新,我们有时候想局部更新,不够灵活

参考网上有人总结,我觉得很有道理,摘抄总结如下:

数据库访问分为这么几种

  1. 写 sql,各个 db 差异要自己适配
  2. 写 dsl,屏蔽了 db 差异,自动适配
  3. 运行时或编译时自动合成 sql,屏蔽 db 差异

我们其实要的就是既能写SQL,又能写DSL,还能运行时或编译时合成SQL,如果DSL不支持,也是极好的。

现有的解决方式

我们既想要JPA的优点,又想到Mybatis的灵活,我想自己SQL,我就用Mybatis,我觉得能通过领域模型解决的,我又希望用JPA。

两者结合,一个项目里既有Mybatis,又有JPA。实际上这个项目里同时用,我这里没有尝试过,猜测一下对于一个实体类是不是要写两个接口,一个是JPA的,一个是Mybatis的。

当然也有人说,用Mybatis Plus,在这里我只能说确实对Mybatis有很多的加强,但也有很多不完美的地方。这个仁者见仁,智者见智, 不做太多的评论。

Mybatis Jpa 介绍

这里介绍一个自己的framework,实现了部分JPA规范(优化了JPA规范的一些不灵活)。框架本身是基于Mybatis的,所以你用Mybatis的一切操作没有任何问题,只做增强,不做修改。还有只做持久化层,不会入侵你的业务代码。介绍一下特性:

  • 自动SQL

    继承CURD接口,实现常规SQL的运行时添加

  • 方法定义SQL

    findByxxxOrderByxxx

  • 方法定义SQL优化

    类似于Mybatis里的if test 标签,实现传入空是查全部

  • 级联查询(只有一级)

    就是one to one, one to many, many to many

  • 级联查询优化

    定义哪些方法需要级联或不级联

  • 主键支持

  • 分页支持

  • java代码级构建复杂查询

  • java代码级触发器

还有可自行扩展主键方式,不同的数据库分页,不同的数据库序列主键。可以让你在Mybatis和JPA之间随心所欲的切换。而无需定义两个操作数据库的mapper或 repository。

吹了这么多,你可以理解为一个软文吧。不过这个软文也只是纯技术的落地型。

文档地址: zhouxx.github.io/boot-plus/#…

github地址: github.com/zhouxx/boot…boot-plus-mybatis-jpa 。已上中央仓库,可以直接尝试。

另外提供了一些例子: github.com/zhouxx/boot…