对于大型项目,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 中没有任何东西可以阻止您在大型项目中使用它,最近的 QueryDSLsupport 可能会对您有所帮助。 This is an example 使用 QueryDSL 来定位 Hibernate。

如果您预见到复杂的查询,并且在没有 JPA 的情况下使用 Hibernate 对象感觉很舒服,我认为另一种组合可能是将简单的 Spring Data Repositorys 放在具有您可能需要的特定方法的复杂的基于 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 介绍

Spring Data JPA 与 MyBatis 对比分析

(转) Spring Data 系列之JPA

使用 spring-data-jpa 自定义 ItemReader

HibernateMybatis与Spring Data JPA的区别

Spring Data JPA系列4:Spring声明式事务处理与多数据源支持