对于大型项目,Spring Data JPA 与 Hibernate 有何不同?
Posted
技术标签:
【中文标题】对于大型项目,Spring Data JPA 与 Hibernate 有何不同?【英文标题】:How does Spring Data JPA differ from Hibernate for large projects? 【发布时间】:2012-09-29 05:49:18 【问题描述】:我很难决定是否应该在新项目中坚持使用 Hibernate,还是继续使用 JPA 和新的 Spring Data 实现。
Spring Data 框架适用于大型项目还是具有适度查询要求的小型项目?
虽然我确实看到了使用 @Query
注释在代码缩减方面的优势,但您如何处理动态查询?当你想实现一个相当复杂的 save() 方法时怎么办?
文档说要创建一个自定义接口和实现,您的主存储库实现,但是如果您需要访问 crud 存储库本身的任何超级方法怎么办? crud 存储库实现了自定义存储库 - 而不是相反。这似乎是一个奇怪的设计。
我非常不确定这个框架是否能够应对复杂和大型应用程序的挑战。我从来没有遇到过 Hibernate 的很多问题,我正在考虑坚持使用旧的可靠而不是 Spring Data JPA。
我该怎么办?如果我使用 Spring Data JPA,我会遇到哪些无法预料的并发症和成本?
【问题讨论】:
据我所知,差别不大。选择你更舒服的那个。为什么要辩论? 我显然更喜欢 Hibernate,但如果我能做同样的事情并提高工作效率,我宁愿采用更新的方法。但是,如果 Hibernate 仍然更强大,并且我遇到的问题会少很多,那么这就是我想知道的。 JPA 是 ORM 的泛化,它使用 Hibernate 作为众多实现之一。你将什么权力赋予其中一个而不是另一个? JPA 是一个标准,但我认为两者之间没有什么区别。为了充分披露,我会说我不关心任何一个。两者都为您生成 SQL。我宁愿自己写。 ORM 并不适用于所有问题和每个用户。 我同意。当只涉及 JPA 或 Hibernate 时,我每次都会选择 Hibernate。老实说,我不太喜欢 JPA 实现本身。 IDEA 中的 IDE 支持实际上仍然很糟糕,如果应用程序启动时映射不正确,它会抱怨而不是让单元测试运行。我对 JPA 还有很多其他的挑剔。我实际上有点喜欢旧的 Hibernate XML 映射文件。它的优点是使我的对象看起来也不那么杂乱。 Spring Data JPA 提供了许多新功能,所以我终于想知道是否值得切换。 “Spring Data”不是 JPA 或任何东西的实现。它只需要一个现有的 JPA 实现并简化您提供给它的内容。 JPA 实现仍然在幕后完成所有工作 【参考方案1】:所以,spring-data
做了一些额外的魔法来帮助处理复杂的查询。一开始很奇怪,您在文档中完全跳过了它,但它确实强大且有用。
它包括创建一个自定义的Repository
和一个自定义的 `RepositoryImpl' 并告诉 Spring 在哪里可以找到它。这是一个例子:
配置类 - 指向您仍然需要的 xml 配置,注释指向您的存储库包(它现在会自动查找 *Impl
类):
@Configuration
@EnableJpaRepositories(basePackages = "com.examples.repositories")
@EnableTransactionManagement
public class MyConfiguration
jpa-repositories.xml - 告诉Spring
在哪里可以找到您的存储库。还告诉Spring
查找具有CustomImpl
文件名的自定义存储库:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<jpa:repositories base-package="com.example.repositories" repository-impl-postfix="CustomImpl" />
</beans>
MyObjectRepository
- 您可以在这里放置带注释和未注释的查询方法。请注意此存储库接口如何扩展 Custom
之一:
@Transactional
public interface MyObjectRepository extends JpaRepository<MyObject, Integer>, MyObjectRepositoryCustom
List<MyObject> findByName(String name);
@Query("select * from my_object where name = ?0 or middle_name = ?0")
List<MyObject> findByFirstNameOrMiddleName(String name);
MyObjectRepositoryCustom
- 更复杂且无法通过简单查询或注释处理的存储库方法:
public interface MyObjectRepositoryCustom
List<MyObject> findByNameWithWeirdOrdering(String name);
MyObjectRepositoryCustomImpl
- 您实际上使用自动连接的EntityManager
实现这些方法:
public class MyObjectRepositoryCustomImpl implements MyObjectRepositoryCustom
@Autowired
private EntityManager entityManager;
public final List<MyObject> findByNameWithWeirdOrdering(String name)
Query query = query(where("name").is(name));
query.sort().on("whatever", Order.ASC);
return entityManager.find(query, MyObject.class);
令人惊讶的是,这一切都汇集在一起,当您这样做时,来自两个接口(以及您实现的 CRUD 接口)的方法都会显示出来:
myObjectRepository.
你会看到:
myObjectRepository.save()
myObjectRepository.findAll()
myObjectRepository.findByName()
myObjectRepository.findByFirstNameOrMiddleName()
myObjectRepository.findByNameWithWeirdOrdering()
确实有效。您将获得一个查询界面。 spring-data
真的为大型应用程序做好了准备。而且,您可以推送到简单或注释的查询越多,您的情况就越好。
所有这些都记录在Spring Data Jpa site。
祝你好运。
【讨论】:
这实际上是我尝试过的,它在一定程度上起作用。我遇到的问题是如果你想覆盖 save() 怎么办?例如,假设您正在保存一个博客,并且您想在 save() 方法中处理/保存与其关联的标签,因为将它放在服务中没有什么意义。使用原始 Hibernate 很容易做到这一点,但我没有看到使用 Spring JPA 的好方法。不过,我会将您的答案标记为正确,因为它是正确的。这基本上就是你可以用 Spring Data JPA 做的事情。我想我会坚持使用 Hibernate。这个答案肯定会帮助其他人。 你可以实现你自己的JpaRepository
-> MyJpaRepository
。您还必须创建一个MyJpaRepositoryFactoryBean
,但如果您设置正确,您可以覆盖 .save() 方法。这是 Spring Data JPA 文档:static.springsource.org/spring-data/data-jpa/docs/current/… 不要放弃!
@Picrochole 你如何解释“底层应用程序”?调用 DAO 的服务是否在层级较低?【参考方案2】:
我在具有简单查询需求的小型和大型项目中使用过 Spring Data JPA。主要优点是甚至不必使用 @Query
注释。 Spring Data 中没有任何东西可以阻止您在大型项目中使用它,最近的 QueryDSL
support 可能会对您有所帮助。 This is an example 使用 QueryDSL 来定位 Hibernate。
如果您预见到复杂的查询,并且在没有 JPA 的情况下使用 Hibernate 对象感觉很舒服,我认为另一种组合可能是将简单的 Spring Data Repository
s 放在具有您可能需要的特定方法的复杂的基于 Hibernate 的对象旁边。将 Hibernate 实现扭曲到 Spring Data JPA 结构中可能不那么麻烦。
【讨论】:
我想我宁愿使用相同一致的 api 进行查询,而不是在同一个项目中混合和匹配。对于复杂的 spring 数据 jpa 内容,我仍然没有找到一个好的解决方案,而且由于我通常对 jpa 有很多挑剔,我想我可能更乐意接受 hibernate 作为我的 orm。我会有很多复杂的查询,而且我负担不起 40/60 的混合。这对我来说不值得:( 您也可以直接使用 Querydsl 而无需 Spring Data,它在 JPA 之上为您提供了一个强大的查询层。【参考方案3】:Spring JPA 将为您提供大量使用查询方法声明编写 SQL 甚至一些 HQL 的抽象。 Spring JPA 以其查询生成而大放异彩,但是当您想要一个纯粹的休眠解决方案时,您可以根据需要进行自定义,因为 Spring JPA 仍然基于休眠。查看文档http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html 了解更多信息。
【讨论】:
以上是关于对于大型项目,Spring Data JPA 与 Hibernate 有何不同?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA 与 MyBatis 对比分析
使用 spring-data-jpa 自定义 ItemReader