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

什么时候不应该使用Hibernate或Spring Data JPA?

另外,Spring JDBC模板什么时候比Hibernate和Spring Data JPA表现更好?


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

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

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

Spring JDBC要轻量级得多,它是为本地查询而设计的,如果您只想单独使用JDBC,那么最好使用Spring JDBC来处理JDBC的冗长性。

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

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

JPA: Java持久化api,提供了从Java对象持久化、读取、管理数据到数据库关系的规范。 Hibernate:有各种实现jpa的提供者。冬眠就是其中之一。所以我们还有其他的提供者。但是如果使用jpa和spring,它允许您在将来切换到不同的提供商。 Spring Data JPA:这是JPA之上的另一层,Spring提供了它使您的工作更容易。

因此,让我们了解spring data jpa和spring + hibernate是如何工作的


Spring Data JPA:

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

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

我不同意SpringJPA使生活变得简单。是的,它提供了一些类,您可以快速地创建一些简单的DAO,但实际上,这是您所能做的全部。 如果你想做一些比findById()或save更多的事情,你必须经历地狱:

在org.springframework.data.repository类中没有EntityManager访问权限(这是基本的JPA类!) 自己的事务管理(不允许休眠事务) 多个数据源配置的巨大问题 没有数据源池(HikariCP必须作为第三方库使用)

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

不幸的是,SpringJPA是基于反射的,有时您需要将方法名或实体包指向注释(!)。这就是为什么任何重构都会导致大崩溃。 遗憾的是,@Transactional只适用于主DS:(所以,如果你有多个数据源,请记住- transactions只适用于主DS:)

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

Hibernate是JPA兼容的,SpringJPA是Spring兼容的。当SpringJPA可以在Spring - SpringBoot中使用时,您的HibernateJPA DAO可以与JavaEE或Hibernate独立使用

什么时候不应该使用Hibernate或Spring Data JPA?此外,什么时候Spring JDBC模板比Hibernate / Spring Data JPA执行得更好?

只有当您需要使用很多join或者需要使用具有多个数据源连接的Spring时才使用Spring JDBC。一般来说,避免使用JPA进行join。

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

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

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

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

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

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

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查询,几乎不必与库对抗。