Spring Data JPA 中的CrudRepository和JpaRepository接口之间有什么区别?
当我在网络上看到示例时,我发现它们在这里可以互换使用。
它们之间有什么区别?
您为什么要一个使用另一个?
JpaRepository
扩展了PagingAndSortingRepository
,后者又扩展了CrudRepository
。
它们的主要功能是:
CrudRepository
主要提供 CRUD 功能。PagingAndSortingRepository
提供了对记录进行分页和排序的方法。JpaRepository
提供了一些与 JPA 相关的方法,例如刷新持久性上下文和删除批处理中的记录。由于上述继承, JpaRepository
将具有CrudRepository
和PagingAndSortingRepository
所有功能。因此,如果您不需要存储库具有JpaRepository
和PagingAndSortingRepository
提供的功能,请使用CrudRepository
。
Ken 的回答基本上是正确的,但我想提一下 “您为什么要在另一个上使用一个?” 您的问题的一部分。
您为存储库选择的基本接口有两个主要目的。首先,允许 Spring Data 存储库基础结构找到您的接口并触发代理创建,以便将接口实例注入客户端。第二个目的是在接口中引入所需的功能,而不必声明额外的方法。
Spring Data 核心库附带两个基本接口,它们公开了一组专用功能:
CrudRepository
-CRUD 方法PagingAndSortingRepository
分页和排序的方法(扩展了CrudRepository
)各个商店模块(例如,针对 JPA 或 MongoDB)公开了这些基本接口的商店特定扩展,以允许访问商店特定功能,例如冲洗或专用批处理,这些功能考虑了一些商店特定情况。对于这样的一个例子是deleteInBatch(…)
的JpaRepository
其是从不同delete(…)
因为它使用一个查询,以删除给定实体这是更高性能的但带有不触发 JPA 定义的级联的副作用(如规格定义了它)。
我们通常建议不要使用这些基本接口,因为它们会将底层的持久性技术公开给客户端,从而加强了它们与存储库之间的耦合。另外,您与存储库的原始定义有所不同,该存储库基本上是 “实体集合”。因此,如果可以的话,请继续使用PagingAndSortingRepository
。
直接取决于所提供的基本接口之一的缺点是双重的。他们两个都可以被认为是理论上的,但我认为了解以下几点很重要:
Page
或Pageable
Spring Data 与 commons-lang 或 Guava 之类的其他通用库没有什么不同。只要提供合理的利益,就可以了。CrudRepository
,您可以一次公开一套完整的持久性方法。这在大多数情况下也可能很好,但是您可能会遇到想要对公开的方法获得更细粒度控制的情况,例如创建不包含save(…)
和delete(…)
ReadOnlyRepository
delete(…)
CrudRepository
方法。解决这两个缺点的方法是设计您自己的基本存储库接口,甚至是其中的一组。在许多应用程序中,我看到了类似以下内容:
interface ApplicationRepository<T> extends PagingAndSortingRepository<T, Long> { }
interface ReadOnlyRepository<T> extends Repository<T, Long> {
// Al finder methods go here
}
第一个存储库接口是一些通用的基础接口,该接口实际上仅修复点 1,而且将 ID 类型Long
为 Long 以保持一致性。第二个接口通常具有CrudRepository
和PagingAndSortingRepository
复制的find…(…)
方法,但不公开操作方法。 在参考文档中阅读有关该方法的更多信息。
存储库抽象使您可以选择完全由架构和功能需求驱动的基础存储库。如果适用,请使用开箱即用的提供的接口,并在必要时制作自己的存储库基础接口。除非不可避免,否则请远离商店特定的存储库接口。