ChatGPT解决这个技术问题 Extra ChatGPT

Hibernate 和 Spring Data JPA 有什么区别

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

@NeilStockton 要求对两种技术进行比较并不是在征求意见。

V
Vlad Mihalcea

Hibernate 是一个 JPA 实现,而 Spring Data JPA 是一个 JPA 数据访问抽象。如果没有 JPA 提供程序,Spring Data JPA 将无法工作。

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

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

Spring JDBC 更轻量级,它用于原生查询,如果你只打算单独使用 JDBC,那么你最好使用 Spring JDBC 来处理 JDBC 冗长。

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


那么这是否意味着 Spring Data JPA 不能独立存在?也就是说,在底层,它使用了 JPA 提供者之一(如 Hibernate、Eclipselink 或任何其他 JPA 提供者)?
我的意思是如果我只使用休眠,休眠级别的配置很少,如果我使用spring data jpa,那看起来比休眠容易得多。从这个意义上说,我问了你这个问题。
更准确地说,到目前为止一切正常,您只需要了解顶层即 Spring Data JPA。除了第一个例外,您可能必须了解较低级别,即 Hibernate、JDBC 和数据库。
@CuriousMind 不,Spring Data 不独立存在(工作)。它默认使用 Hibernate 实现,您可以注意到 hibernate-core 作为 spring-data-jpa 中的子部门之一
阅读 MWT 课程的每个人:MÄÄÄHH
A
Adnan

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

JPA:Java 持久化 api,它提供了从 Java 对象到数据库关系的持久化、读取和管理数据的规范。 Hibernate:有各种实现 jpa 的提供程序。休眠就是其中之一。所以我们也有其他供应商。但是如果将 jpa 与 spring 一起使用,它可以让您将来切换到不同的提供程序。 Spring Data JPA :这是 jpa 之上的另一层,spring 提供它让您的生活更轻松。

那么让我们了解一下 spring data jpa 和 spring + hibernate 是如何工作的——

春季数据 JPA:

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

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


那么Spring Data JPA底层实现是什么,是hibernate吗?因为我使用PagingAndSortingRepository的时候,在控制台显示Hibernate日志。
Spring Data JPA 默认使用 Hibernate 实现。如果你看到 spring-boot-starter-data-jpa 的传递依赖,你可以在那里看到 hibernate-core
C
Cody Gray

我不同意 SpringJPA 让生活变得轻松。是的,它提供了一些类,你可以快速制作一些简单的 DAO,但事实上,你能做的只有这些。如果你想做比 findById() 或保存更多的事情,你必须经历地狱:

org.springframework.data.repository 类中没有 EntityManager 访问权限(这是基本的 JPA 类!)

自己的事务管理(不允许休眠事务)

多个数据源配置存在巨大问题

没有数据源池(HikariCP 必须作为第三方库使用)

为什么自己的事务管理是一个缺点?由于 Java 1.8 允许在接口中使用默认方法,基于 Spring 注释的事务,simple 不起作用。

不幸的是,SpringJPA 是基于反射的,有时您需要将方法名称或实体包指向注解(!)。这就是为什么任何重构都会导致严重崩溃的原因。可悲的是,@Transactional 仅适用于主要 DS :( 因此,如果您有多个数据源,请记住 - 事务仅适用于主要 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 进行连接。

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


道霸,真的吗?如果您不喜欢 jpql 的类型安全(我不喜欢),那么 JPA 有一个类型安全标准 API……标准 JPA 比那个糟糕的替代方案要好。
r
raiks

Spring Data 是在 JPA 之上的一个便利库,它抽象出许多东西并将 Spring 的魔力(喜欢与否)带入持久性存储访问。它主要用于处理关系数据库。简而言之,它允许您声明具有类似 findByNameOrderByAge(String name); 的方法的接口,这些方法将在运行时解析并转换为适当的 JPA 查询。

它在 JPA 顶部的位置使得它的使用很有吸引力:

不懂 SQL 或对 SQL 知之甚少的新手开发人员。这是一个灾难的秘诀,但如果项目是微不足道的,他们可以侥幸逃脱。经验丰富的工程师,他们知道自己在做什么,并希望快速完成任务。这可能是一个可行的策略(但请进一步阅读)。

根据我对 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 尝试将它们序列化时,这会导致 Stack Overflow 错误(由于循环引用),从而迫使您陷入丑陋的摆弄/变通方法。这个问题与 Spring Data 无关,因为它是 JPA 问题。但是,由于 JPA 是 Spring Data 的基础,因此您可以“免费”获得它。
编辑了帖子并添加了一个示例。
G
GPopat

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

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


M
Muhammad Waqas Dilawar

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

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

当你使用 JDBC 时,你需要使用 SQL 查询,所以如果你精通 SQL,那就去 JDBC。


什么是wrt?
关于