【发布时间】:2012-12-10 10:44:06
【问题描述】:
Spring Data JPA 中的CrudRepository 和JpaRepository 接口有什么区别?
当我在网上看到这些示例时,我发现它们在那里可以互换使用。
它们有什么区别?
你为什么要使用一个而不是另一个?
【问题讨论】:
标签: java spring jpa spring-data spring-data-jpa
Spring Data JPA 中的CrudRepository 和JpaRepository 接口有什么区别?
当我在网上看到这些示例时,我发现它们在那里可以互换使用。
它们有什么区别?
你为什么要使用一个而不是另一个?
【问题讨论】:
标签: java spring jpa spring-data spring-data-jpa
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,您一次公开了一套完整的持久性方法。 这在大多数情况下可能也很好,但您可能会遇到希望对公开的方法进行更细粒度控制的情况,例如创建一个不包含CrudRepository 的save(…) 和delete(…) 方法的ReadOnlyRepository。解决这两个缺点的方法是制作自己的基础存储库接口,甚至是其中的一组。在很多应用程序中,我都看到过这样的事情:
interface ApplicationRepository<T> extends PagingAndSortingRepository<T, Long> { }
interface ReadOnlyRepository<T> extends Repository<T, Long> {
// Al finder methods go here
}
第一个存储库接口是一些通用的基本接口,它实际上只修复了第 1 点,但也将 ID 类型绑定为 Long 以保持一致性。第二个接口通常具有从CrudRepository 和PagingAndSortingRepository 复制的所有find…(…) 方法,但不公开操作方法。在reference documentation 中阅读有关该方法的更多信息。
存储库抽象允许您选择完全由您的架构和功能需求驱动的基本存储库。如果适合,请使用开箱即用的接口,如有必要,请制作您自己的存储库基础接口。除非不可避免,否则请远离商店特定的存储库接口。
【讨论】:
所有答案都为问题提供了足够的细节。不过,让我再补充一点。
我们为什么要使用这些接口:
哪个接口做什么:
何时使用哪个界面:
根据http://jtuts.com/2014/08/26/difference-between-crudrepository-and-jparepository-in-spring-data-jpa/
通常最好的办法是使用 CrudRepository 或 PagingAndSortingRepository,具体取决于您是否需要排序和分页。
如果可能,应避免使用 JpaRepository,因为它将您的存储库与 JPA 持久性技术联系在一起,并且在大多数情况下,您甚至可能不会使用它提供的额外方法。
【讨论】:
下面是CrudRepository和JpaRepository的区别:
CrudRepositoryCrudRepository 是一个基本接口并扩展了Repository 接口。CrudRepository主要提供CRUD(创建、读取、更新、删除)操作。saveAll()方法的返回类型是Iterable。CrudRepository 的存储库。JpaRepositoryJpaRepository 扩展 PagingAndSortingRepository 扩展 CrudRepository。JpaRepository 提供 CRUD 和分页操作,以及 flush()、saveAndFlush() 和 deleteInBatch() 等其他方法。saveAll() 方法的返回类型是List。JpaRepository。【讨论】:
Crud Repository 是基础接口,它充当标记接口。
JPA 存储库还扩展了 PagingAndSorting 存储库。 它提供了所有对实现分页有用的方法。 Crud Repository 不提供实现分页和排序的方法
【讨论】:
CrudRepository 不是标记接口。 baeldung.com/…。此外,代码中检查它的实例很少(可能为 0 个),因此它也不能作为一个实例。