Hibernate和Spring Data JPA有什么区别


207

Hibernate和Spring Data JPA之间的主要区别是什么?什么时候不应该使用Hibernate或Spring Data JPA?另外,Spring JDBC模板何时可以比Hibernate / Spring Data JPA更好地执行?


7
@NeilStockton要求在两种技术之间进行比较并不是要征求意见。
菲利普·雷戈

Answers:


262

Hibernate是JPA实现,而Spring Data JPA是JPA数据访问抽象。没有JPA提供者,Spring Data JPA无法工作。

Spring Data提供了DDD Repository模式或旧式GenericDao自定义实现的解决方案。它还可以通过方法名称约定代表您生成JPA查询。

使用Spring Data,您可以使用Hibernate,Eclipse Link或任何其他JPA提供程序。使用Spring或Java EE的一个非常有趣的好处是,您可以使用@Transactional注释以声明方式控制事务边界

Spring JDBC更轻量级,并且用于本机查询,如果您仅打算单独使用JDBC,那么最好使用Spring JDBC处理JDBC详细信息。

因此,Hibernate和Spring Data是互补的,而不是竞争对手。


52
那么这是否意味着Spring Data JPA无法自身存在?也就是说,它使用了JPA提供程序之一(例如Hibernate,Eclipselink或任何其他JPA提供程序)?
CuriousMind

我的意思是,如果仅使用休眠模式,则休眠级别的配置很少。如果使用spring数据jpa,则看起来比休眠容易得多。从这个意义上说,我问你这个问题。
阿西夫·穆斯塔克

1
更准确地说,到目前为止,一切工作正常,您只需要了解顶层即Spring Data JPA。除了第一个例外,您可能必须了解较低的级别,即Hibernate,JDBC 数据库。
Marmite Bomber

138

我们在这里使用3种不同的东西:

  1. JPA:Java持久性api,它提供规范,用于持久化,读取,管理从Java对象到数据库中关系的数据。
  2. Hibernate:有许多实现jpa的提供程序。休眠是其中之一。因此,我们也有其他提供商。但是,如果将spring与jpa结合使用,则将来可以切换到其他提供程序。
  3. Spring Data JPA:这是jpa之上的另一层,Spring提供了这一层,使您的生活变得轻松。

因此,让我们了解一下spring数据jpa和spring + hibernate的工作原理-


Spring Data JPA:

假设您正在为应用程序使用spring + hibernate。现在,您需要具有dao接口和实现,您将在其中使用hibernate的SessionFactory编写crud操作。假设您正在为Employee类编写dao类,明天在您的应用程序中,您可能需要为任何其他实体编写类似的crud操作。因此,我们可以在此处看到很多样板代码。

现在,Spring数据jpa允许我们通过扩展其存储库(crudrepository,jparepository)来定义dao接口,以便在运行时为您提供dao实现。您不再需要编写dao实现,这就是spring data jpa如何使您的生活变得轻松的原因。


3
那么,Spring Data JPA的底层实现是什么,它是休眠的吗?因为当我使用PagingAndSortingRepository时,它在控制台中显示了Hibernate日志。
Vicky '18

2
春季数据JPA使用Hibernate实现默认情况下。如果你看到弹簧引导起动数据JPA的传递依赖,你可以看到休眠核心有
IamVickyAV

28

我不同意SpringJPA使生活变得轻松。是的,它提供了一些类,您可以快速制作一些简单的DAO,但实际上,您可以做的只是。如果要执行除findById()或保存以外的其他操作,则必须经历地狱:

  • org.springframework.data.repository类中没有EntityManager访问(这是基本的JPA类!)
  • 自己的交易管理(不允许休眠交易)
  • 多个数据源配置带来的巨大问题
  • 没有数据源池(必须将HikariCP用作第三方库)

为什么自己的交易管理是不利的?由于Java 1.8允许接口中使用默认方法,因此基于Spring注释的事务就无法使用。

不幸的是,SpringJPA基于反射,有时您需要将方法名称或实体包指向注释(!)。这就是任何重构都会导致严重崩溃的原因。可悲的是,@ Transactional仅适用于主要DS :(因此,如果您有多个DataSource,请记住-事务仅适用于主要DS :)

Hibernate和Spring Data JPA之间的主要区别是什么?

Hibernate是JPA兼容的,SpringJPA是Spring的。当SpringJPA可以在Spring中使用时,您的HibernateJPA DAO可以与JavaEE或Hibernate Standalone一起使用-例如,SpringBoot

什么时候不应该使用Hibernate或Spring Data JPA?另外,Spring JDBC模板何时可以比Hibernate / Spring Data JPA更好地执行?

仅当需要使用大量Join或需要使用具有多个数据源连接的Spring时,才使用Spring JDBC。通常,避免使用JPA for Joins。

但我的一般建议是使用全新的解决方案-Daobab(http://www.daobab.io)。Daobab是我的Java以及任何JPA引擎集成商,我相信它将对您的工作有很大帮助:)


2
Daobab,真的吗?如果您不喜欢jpql的类型安全性(我不喜欢),则JPA具有类型安全性标准API。
ymajoros

8

Spring Data是一个便捷库,它在顶部JPA简化了许多内容,并将Spring魔术(无论是否喜欢)带入了持久性存储访问。它主要用于处理关系数据库。简而言之,它允许您声明具有类似方法的接口,这些方法findByNameOrderByAge(String name);将在运行时进行解析并转换为适当的JPA查询。

它的放置位置JPA使它具有以下用途:

  1. 不太了解SQL或不太了解的新手开发人员。这是灾难的根源,但如果项目不重要,他们可以摆脱灾难。

  2. 经验丰富的工程师知道他们的工作,并希望快速完成工作。这可能是一种可行的策略(但请进一步阅读)。

根据我的经验Spring Data,它的魔力太大(通常适用于此Spring)。我开始在一个项目中大量使用它,最终遇到了几个无法解决的问题,最终导致丑陋的解决方法。后来,我阅读了其他用户的抱怨,并意识到这些问题通常是针对的Spring Data。例如,检查导致大量调查/宣誓的这个问题:

 public TourAccommodationRate createTourAccommodationRate(
        @RequestBody TourAccommodationRate tourAccommodationRate
    ) {
        if (tourAccommodationRate.getId() != null) {
            throw new BadRequestException("id MUST NOT be specified in a body during entry creation");
        }

        // This is an ugly hack required for the Room slim model to work. The problem stems from the fact that
        // when we send a child entity having the many-to-many (M:N) relation to the containing entity, its
        // information is not fetched. As a result, we get NPEs when trying to access all but its Id in the
        // code creating the corresponding slim model. By detaching the entity from the persistence context we
        // force the ORM to re-fetch it from the database instead of taking it from the cache

        tourAccommodationRateRepository.save(tourAccommodationRate);
        entityManager.detach(tourAccommodationRate);
        return tourAccommodationRateRepository.findOne(tourAccommodationRate.getId());
    }

我最终走到较低的层次,开始使用JDBI-一个不错的库,它具有足够的“魔力”来将您从样板中解救出来。有了它,您就可以完全控制SQL查询,几乎不需要与库打架。


这是一个很好的答案,但是如果您可以列出最常见的情况并进一步详细说明,这将非常有帮助。这将成为一个很好的答案。谢谢
约翰

好吧,考虑到我已经有一段时间没有使用Spring Data了,要想回顾那些内容并不容易-我将不得不浏览旧代码并添加更多注释。但是,烦恼之一就是我的头脑-在JPA中,对象经常必须互相引用(例如,对于级联操作)。当Spring尝试序列化它们时,这会导致堆栈溢出错误(由于循环引用),从而使您陷入难看的摆弄/变通方法。尽管此问题是JPA问题,但与Spring Data密切相关。但是,由于JPA是Spring Data的基础,因此您可以“免费”获得它。
袭击

编辑了帖子,并添加了另一个示例。
突袭

1

Hibernate是“ JPA”的实现,“ JPA”是数据库中Java对象的规范。

我建议使用wrt JPA,因为您可以在不同的ORMS之间切换。

使用JDBC时,您需要使用SQL查询,因此,如果您精通SQL,则可以使用JDBC。


1

如果您喜欢简单性和对SQL查询的更多控制,那么我建议使用Spring Data / Spring JDBC。

它在JPA中有大量的学习曲线,有时很难调试问题。另一方面,当您完全控制SQL时,优化查询和提高性能变得容易得多。您可以轻松地与DBA或对数据库有更好了解的人共享SQL。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.