Spring Data JPA中的CrudRepository和JpaRepository接口有什么区别?

2022-08-31 03:59:43

Spring Data JPA中的CrudRepositoryJpaRepository接口有什么区别?

当我在网络上看到这些例子时,我看到它们在那里可以互换使用。

它们之间有什么区别?

为什么要使用一个而不是另一个?


答案 1

JpaRepository扩展了PagingAndSortingRepository,这反过来又扩展了CrudRepository

它们的主要功能是:

由于上面提到的继承,将具有 和 的所有功能。因此,如果您不需要存储库具有 和 提供的功能,请使用 。JpaRepositoryCrudRepositoryPagingAndSortingRepositoryJpaRepositoryPagingAndSortingRepositoryCrudRepository


答案 2

Ken的回答基本上是正确的,但我想插话说一下你问题的“为什么你想使用一个而不是另一个?”部分。

基本

您为存储库选择的基本接口有两个主要用途。首先,您允许Spring Data存储库基础架构找到您的接口并触发代理创建,以便将接口的实例注入客户端。第二个目的是将尽可能多的功能拉入到接口中,而不必声明额外的方法。

通用接口

Spring Data核心库附带两个基本接口,公开了一组专用功能:

  • CrudRepository- CRUD 方法
  • PagingAndSortingRepository- 分页和排序的方法(扩展CrudRepository)

特定于商店的接口

各个存储模块(例如,用于 JPA 或 MongoDB)公开了这些基本接口的特定于存储的扩展,以允许访问特定于存储的功能,如刷新或专用批处理,这些功能考虑了一些存储细节。这方面的一个例子是不同的,因为它使用查询来删除给定的实体,该实体的性能更高,但附带的副作用是不触发JPA定义的级联(如规范所定义的那样)。deleteInBatch(…)JpaRepositorydelete(…)

我们通常建议不要使用这些基本接口,因为它们向客户端公开了底层持久性技术,从而加强了它们与存储库之间的耦合。另外,你离存储库的原始定义有点不同,它基本上是“实体的集合”。因此,如果可以的话,请继续使用 .PagingAndSortingRepository

自定义存储库基本接口

直接依赖于提供的基本接口之一的缺点是双重的。它们都可能被认为是理论上的,但我认为它们很重要:

  1. 根据Spring Data存储库接口,将您的存储库接口耦合到库。我不认为这是一个特别的问题,因为无论如何,你可能会在你的代码中使用抽象。Spring Data与任何其他通用库(如commons-lang或Guava)没有任何不同。只要它提供合理的收益,就没问题。PagePageable
  2. 通过扩展例如CrudRepository,您可以一次公开一组完整的持久性方法。在大多数情况下,这可能也很好,但是您可能会遇到希望对方法公开进行更细粒度控制的情况,例如,创建一个不包含 和 方法的情况。ReadOnlyRepositorysave(…)delete(…)CrudRepository

这两个缺点的解决方案是创建自己的基本存储库接口,甚至是一组接口。在很多应用程序中,我都看到过这样的东西:

interface ApplicationRepository<T> extends PagingAndSortingRepository<T, Long> { }

interface ReadOnlyRepository<T> extends Repository<T, Long> {

  // Al finder methods go here
}

第一个存储库接口是一些通用的基本接口,它实际上只修复了第 1 点,但也将 ID 类型绑定在一起以实现一致性。第二个接口通常包含从 复制的所有方法,但不公开操作方法。在参考文档中阅读有关该方法的更多信息。Longfind…(…)CrudRepositoryPagingAndSortingRepository

总结 - tl;博士

存储库抽象允许您选择完全由您的体系结构和功能需求驱动的基本存储库。如果合适,请使用开箱即用的接口,如有必要,请制作自己的存储库基本接口。除非不可避免,否则请远离存储特定的存储库接口。


推荐