Spring Data JDBC / Spring Data JPA vs Hibernate



在现实生活中,人们会选择Spring Data JDBC/Spring Data JPA与Hibernate的典型场景是什么?我想了解这些实现中的任何一种最适合的方案。

正如@Naros所说,标题中目前的问题实际上不起作用。似乎我们真的应该看看 4 个选项,并主要列出每种方法的优点,缺点是没有另一种方法的优点:

没有弹簧数据的 JDBC

您可以 100% 细粒度地控制正在发生的事情。框架不会生成或注入任何内容。这听起来像是一个骗局,但如果你试图调整映射和配置,让一些JPA实现做你可以在java和SQL中简单地写下来的事情,你就会明白这可能是一个很大的优点。

你不必学习JPA,也不必学习Spring Data。我个人认为Spring Data很容易,但我有偏见(见我的个人资料)。但是JPA肯定具有挑战性,一旦你离开了琐碎的实体和设置区域。

  • 无需对域模型进行建模(例如,JPA 需要默认构造函数)

您可能希望使用一些库来减少样板代码。看看:

  • 乔克

  • 米巴蒂斯

  • Spring
  • JdbcTemplate(无需Spring的其余部分即可使用)

  • 查询Dsl

带有 Spring 数据的 JDBC

您可以获得Spring Data的好处,并结合JDBC的好处(见上文):

  • 具有开箱即用的 CRUD 方法的存储库。

  • 支持聚合。见 https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates

  • 在 Spring 基础架构中很好地集成了事务处理、依赖注入、错误转换、分页......

  • 它仍然是一个非常简单的编程模型。SQL语句恰好在人们期望它们发生的时候发生,如果你愿意,你可以在有或没有其他框架支持的情况下回退到简单的JDBC,而不会破坏任何抽象。

  • 使用查询方法扩展存储库的简单方法(您只需定义接口以具有findByLastName方法,Spring 就会动态为您生成它)或@Query注释或自定义方法。

  • 支持分页

休眠(或其他一些JPA实现)没有Spring Data

JPA在JDBC上做了很多事情

  • 缓存(第一级、第二级和查询缓存)

  • 从查询自动创建实例

  • 实体之间的导航

  • 延迟加载

  • 脏检查/跟踪实体更改

随着所有这些事情的发生,可能很难理解正在发生的事情以及为什么。当然,IFF可以正确构建您的应用程序,如果JPA不提供您想要的东西,您可以回退到JDBC。但我多次看到人们未能维持其工作所需的结构。显然,如果您不正确理解 JPA 的工作原理,这尤其困难。

休眠(或其他一些JPA实现)与Spring Data

我在上面列出了Spring Data的好处,只需执行心理复制和粘贴即可。

当然,这使得整个堆栈更加复杂。从带有 spring-data 和休眠标记的许多问题来看,似乎许多开发人员在确定哪个工具做什么时遇到了问题。但从这些问题来看,大多数问题都描述了Hibernate/JPA的问题,而不是Spring Data的问题。

总结一下:

  • 如果需要/需要细粒度控制,请使用 JDBC。

  • 如果你打算使用 JPA,请确保尽早理解它。

  • 如果您选择的持久性技术 Spring 数据提供了一个模块,我会使用它。它会让生活更轻松。但我又有偏见了。

你的问题的一个问题是你似乎暗示Spring Data JPA就像Hibernate,这实际上不是真的。 Spring Data JPA只是一个以spring为中心的包装器,它提供了弹性语义和功能,包装了一个JPA提供程序,Hibernate是其中一个实现。

因此,你不能使用Spring Data JPA,而不包括一些JPA实现,如Hibernate。

然后你问的基本问题是为什么要使用JDBC而不是ORM。 为了理解,您应该花时间了解ORM的好处。 互联网上有许多文章可以为您提供。

但即使在ORM驱动的应用程序中,有时您也需要绕过ORM框架并使用本机SQL,就像在JDBC中一样。 这些情况通常很少见,但当您想要利用某些不受支持的数据库功能或想要最终控制操作结果等时,这是必要的。

使用哪个决定因素最终取决于应用程序的需求。 但是,仅仅因为您选择使用 ORM 框架并不能相互排除像在 JDBC 中那样执行本机查询和 SQL 语句的能力。 这些功能仍然可用,您通常在极少数情况下使用它们。

问题是 jpa 的 Spring 数据是对 jpa 的抽象,这是对 JDBC 的抽象。如果提供不错的功能,即使 jpa 在没有它的情况下也可以使用。随着 Spring 数据休息,它变得非常强大。

但是,框架为您做的越多,您就越需要了解底层技术。如果使用 spring-data-rest 更是如此。最好是从理解sql(设计和查询)开始,然后是jpa(延迟加载,实例状态,实体,可嵌入对象,缓存,查询,事务同步)。

然后你尝试spring-data-jpa,并决定它是否给你的项目带来价值。对于保存,更新,删除和通过id查找操作,它基本上是围绕persistmergeremovefindEntityManager方法的包装器。Spring data JPA 的主要优点是查询支持,但 querydsl 也是一个不错的选择。在这两种情况下,都需要清楚地了解 JPA 的工作原理。首先要做的是打开 SQL 日志记录,以查看对于给定的数据库访问,您的 jpa 实现是否执行了 dba 认为正确的查询。例如,对不在缓存中的实体进行预先加载会导致 1+n 选择,您的单元测试将通过,问题将在生产中开始。spring-data-jpa不会为您解决问题。

除了spring-data-jpa之外,还有许多spring-data-*,其中一些还提供映射注释(例如spring-data-cassandra),这在没有对象数据库映射时很有用。

我正在寻找这个问题的答案。以下比较取自Java Persistent with Spring Data和Hibernate。

我可以采取的一点是,在某些情况下,自定义功能需要修改Spring Data JPA提供的特定于数据库的功能。或者,也许,我们希望避免弹簧数据魔术带来的这种复杂性。

Spring Data自本机 SQL加载 无会话和脏跟踪 没有
JPA Spring DataJDBC
独立于数据库且可移植通常,特定于数据库
通过对象关系映射引入复杂性不太复杂,仍然遵循 Spring 框架原则
基于实体自动生成模式通过程序员端的 DDL 命令生成模式
第一个版本以来的查询派生 自版本2.0 以来的查询派生
使用 JPQL 代码批注的查询和使用的本机 SQL 仅查询
可以重用带有 JPA 注释的类。使用org.springframework.data package中的注释
通过注释对实体之间的关系进行建模,如@OneToMany、@Embedded等。通过类的设计,主要在程序员方面对关系进行建模。
缓存和延迟缓存,无延迟加载
会话,没有脏跟踪

最新更新