Hibernate和Spring Data JPA之间的主要区别是什么?
在什么情况下不应该使用Hibernate或Spring Data JPA?
此外,何时Spring JDBC模板可能比Hibernate和Spring Data JPA表现更好?
Hibernate和Spring Data JPA之间的主要区别是什么?
在什么情况下不应该使用Hibernate或Spring Data JPA?
此外,何时Spring JDBC模板可能比Hibernate和Spring Data JPA表现更好?
Repository
模式或传统GenericDao
自定义实现的解决方案。它还可以通过方法名称约定代表您生成JPA查询。@Transactional
注释声明性地控制事务边界。这里有三个不同的东西:
因此,让我们了解一下spring data jpa和spring + hibernate是如何工作的-
假设您正在使用Spring + Hibernate开发应用程序。现在您需要拥有Dao接口和实现,您将使用Hibernate的SessionFactory编写CRUD操作。假设您正在为Employee类编写Dao类,明天在您的应用程序中,您可能需要为任何其他实体编写类似的CRUD操作。因此,我们可以看到很多样板代码。
现在,Spring Data JPA允许我们通过扩展其repositories(CRUDRepository、JPARepository)来定义Dao接口,因此它会在运行时为您提供Dao实现。您不再需要编写Dao实现。这就是Spring Data JPA如何使您的工作更轻松。
我不同意SpringJPA让生活变得容易。是的,它提供了一些类,可以快速创建一些简单的DAO,但实际上,这就是你所能做的。 如果你想做比findById()或save更多的事情,你必须经历痛苦:
为什么自己的事务管理是一个缺点?由于Java 1.8允许接口中的默认方法,基于Spring注解的事务处理非常简单实用。
不幸的是,SpringJPA基于反射,有时需要在注释中指定方法名或实体包名。这就是为什么任何重构都会造成严重崩溃。 遗憾的是,@Transactional仅适用于主数据源 :( 因此,如果您有多个数据源,请记住 - 事务只适用于主数据源 :)
Hibernate和Spring Data JPA之间的主要区别是什么?
Hibernate兼容JPA,SpringJPA兼容Spring。你的HibernateJPA DAO可以与JavaEE或Hibernate Standalone一起使用,而SpringJPA可以在Spring中使用 - 例如SpringBoot。
什么时候不应该使用Hibernate或Spring Data JPA?还有什么情况下Spring JDBC模板可能比Hibernate/Spring Data JPA表现更好?
仅在需要使用大量连接或需要使用具有多个数据源连接的Spring时才使用Spring JDBC。通常,避免在连接方面使用JPA。
但是我的一般建议是使用全新的解决方案 - Daobab(http://www.daobab.io)。 Daobab是我的Java和任何JPA引擎集成器,我相信它将在您的任务中提供很大帮助 :)
EntityManager
,所以这不是一个问题。Spring还可以很容易地声明式地管理事务,不需要自己操心Hibernate的事务。关于多个数据源的“巨大问题”:如果你知道你在做什么,这并不复杂。而且@Transactional
并不只适用于主数据源。关于没有数据源池化的说法:我不知道你为什么这样认为,但这简直是不真实的。 - JesperSpring Data
是建立在JPA
之上的一个方便的库,它抽象了很多东西,并将Spring魔法(喜欢或不喜欢)带入了持久化存储访问中。它主要用于处理关系数据库。简而言之,它允许您声明具有像findByNameOrderByAge(String name);
这样的方法的接口,这些方法将在运行时解析并转换为适当的JPA
查询。
它位于JPA
之上,使得其使用对以下人员诱惑:
不懂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。
“Original Answer”翻译成中文为“最初的回答”。