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
pattern 或旧的 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 是如何工作的——
春季数据 JPA:
假设您正在为您的应用程序使用 spring + hibernate。现在您需要有 dao 接口和实现,您将在其中使用 hibernate 的 SessionFactory 编写 crud 操作。假设您正在为 Employee 类编写 dao 类,明天在您的应用程序中,您可能需要为任何其他实体编写类似的 crud 操作。所以我们可以在这里看到很多样板代码。
现在 Spring data jpa 允许我们通过扩展其存储库(crudrepository,jparepository)来定义 dao 接口,以便它在运行时为您提供 dao 实现。您不再需要编写 dao 实现。这就是 spring data jpa 让您的生活变得轻松的方式。
我不同意 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 引擎集成商,我相信它会对您的任务有很大帮助 :)
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 查询,并且几乎不必与库作斗争。
如果您更喜欢对 SQL 查询的简单性和更多控制,那么我建议您使用 Spring Data/Spring JDBC。
它在 JPA 中的大量学习曲线,有时难以调试问题。另一方面,虽然您可以完全控制 SQL,但优化查询和提高性能变得更加容易。您可以轻松地与 DBA 或对数据库有更好理解的人共享您的 SQL。
Hibernate 是“JPA”的实现,它是数据库中 Java 对象的规范。
我建议使用 wrt JPA,因为您可以在不同的 ORMS 之间切换。
当你使用 JDBC 时,你需要使用 SQL 查询,所以如果你精通 SQL,那就去 JDBC。
不定期副业成功案例分享
hibernate-core
作为spring-data-jpa
中的子部门之一