Spring Data JPA中CrudRepository和JpaRepository接口的区别是什么?
当我在网上看到这些例子时,我发现它们是可以互换使用的。
它们之间的区别是什么?
为什么要用其中一种而不是另一种呢?
Spring Data JPA中CrudRepository和JpaRepository接口的区别是什么?
当我在网上看到这些例子时,我发现它们是可以互换使用的。
它们之间的区别是什么?
为什么要用其中一种而不是另一种呢?
当前回答
Ken的回答基本上是正确的,但我想回答你的问题“为什么你想使用一个而不是另一个?”
基础知识
为存储库选择的基本接口有两个主要目的。首先,您允许Spring Data存储库基础设施找到您的接口并触发代理创建,以便将接口实例注入到客户机中。第二个目的是将尽可能多的功能拉入接口,而不必声明额外的方法。
常用接口
Spring Data核心库附带了两个基本接口,它们公开了一组专用功能:
CrudRepository—CRUD方法 PagingAndSortingRepository—用于分页和排序的方法(扩展CrudRepository)
能找到接口
The individual store modules (e.g. for JPA or MongoDB) expose store-specific extensions of these base interfaces to allow access to store-specific functionality like flushing or dedicated batching that take some store specifics into account. An example for this is deleteInBatch(…) of JpaRepository which is different from delete(…) as it uses a query to delete the given entities which is more performant but comes with the side effect of not triggering the JPA-defined cascades (as the spec defines it).
我们通常建议不要使用这些基本接口,因为它们将底层持久性技术暴露给客户机,从而加强了客户机与存储库之间的耦合。另外,您还偏离了存储库的原始定义,它基本上是“实体的集合”。所以如果可以,请使用PagingAndSortingRepository。
自定义存储库基础接口
直接依赖于所提供的基本接口的缺点有两个。它们都可能被认为是理论性的,但我认为了解它们很重要:
Depending on a Spring Data repository interface couples your repository interface to the library. I don't think this is a particular issue as you'll probably use abstractions like Page or Pageable in your code anyway. Spring Data is not any different from any other general purpose library like commons-lang or Guava. As long as it provides reasonable benefit, it's just fine. By extending e.g. CrudRepository, you expose a complete set of persistence method at once. This is probably fine in most circumstances as well but you might run into situations where you'd like to gain more fine-grained control over the methods expose, e.g. to create a ReadOnlyRepository that doesn't include the save(…) and delete(…) methods of CrudRepository.
解决这两个缺点的方法是创建自己的基本存储库接口,甚至是一组基础存储库接口。在很多应用中,我看到过这样的东西:
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…(…)方法,但不公开操作方法。在参考文档中阅读关于该方法的更多信息。
摘要- tl
存储库抽象允许您选择完全由您的架构和功能需求驱动的基本存储库。如果合适的话,使用现成提供的接口,如果必要的话,制作自己的存储库基础接口。除非不可避免,否则不要使用特定于存储库的接口。
其他回答
所有的答案都为问题提供了足够的细节。不过,让我再补充一点。
为什么我们要使用这些接口:
它们允许Spring找到存储库接口并为它们创建代理对象。 它为您提供了允许您执行一些常见操作的方法(您也可以定义您的自定义方法)。我喜欢这个特性,因为创建一个方法(定义查询和准备好的语句,然后用连接对象执行查询)来做一个简单的操作真的很糟糕!
哪个接口做什么:
CrudRepository:提供CRUD功能 PagingAndSortingRepository:提供对记录进行分页和排序的方法 JpaRepository:提供JPA相关的方法,例如刷新持久化上下文和批量删除记录
何时使用哪个接口:
根据http://jtuts.com/2014/08/26/difference-between-crudrepository-and-jparepository-in-spring-data-jpa/
一般来说,最好的想法是使用CrudRepository或PagingAndSortingRepository,这取决于你是否需要排序和分页。
如果可能的话,应该避免使用JpaRepository,因为它将您的存储库绑定到JPA持久性技术上,在大多数情况下,您可能甚至不会使用它提供的额外方法。
我正在学习Spring Data JPA。它可能会帮助你:
简介:
PagingAndSortingRepository扩展了CrudRepository JpaRepository扩展PagingAndSortingRepository
CrudRepository接口为CRUD操作提供了方法,因此它允许您创建、读取、更新和删除记录,而无需定义自己的方法。
PagingAndSortingRepository提供了使用分页和排序检索实体的附加方法。
最后,JpaRepository添加了一些特定于JPA的更多功能。
spring-data-jpa 3.x的最新更新
从spring-data-jpa 3开始。X与弹簧靴一起使用。6.x和弹簧芯,
结构和层次结构已经修改,看起来更加清晰。
ListCrudRepository扩展了CrudRepository
ListPagingAndSortingRepository扩展了PagingAndSortingRepository
JpaRepository扩展了ListCrudRepository, listpaging和sortingrepository。
所以基本上新引入的ListPagingAndSortingRepository接口,ListCrudRepository现在代表了旧接口的功能,但返回类型为List<T>,而剩余的PagingAndSortingRepository, CrudRepository处理返回类型为Iterable<T>
在新的(3.x)版本中,结构如下:
在过去(3.0之前),许多返回List<T>的声明方法都直接在JpaRepository中声明,但现在这些方法有单独的接口,它们被提取到ListPagingAndSortingRepository, ListCrudRepository中。
(3.x)之前的结构是
我希望从上面的模式中可以清楚地看到,在3中提到的JpaRepository和CrudRepository是如何被修改的。x版本。
In case you plan to migrate spring-data-jpa from 2.x into 3.x (would be necessary if you migrate from spring-boot 2.x to spring-boot 3.x) as illustrated in the above schemas you should expect to have breaking code in cases where you have used the PagingAndSortingRepository in your code, as in the past it was extending from CrudRepository and so your custom repository which extended directly the PagingAndSortingRepository already had access to the methods of CrudRepository. If this is the issue you should fix this by adapting your custom repository to also extend either the ListCrudRepository or the CrudRepository.
Ken的回答基本上是正确的,但我想回答你的问题“为什么你想使用一个而不是另一个?”
基础知识
为存储库选择的基本接口有两个主要目的。首先,您允许Spring Data存储库基础设施找到您的接口并触发代理创建,以便将接口实例注入到客户机中。第二个目的是将尽可能多的功能拉入接口,而不必声明额外的方法。
常用接口
Spring Data核心库附带了两个基本接口,它们公开了一组专用功能:
CrudRepository—CRUD方法 PagingAndSortingRepository—用于分页和排序的方法(扩展CrudRepository)
能找到接口
The individual store modules (e.g. for JPA or MongoDB) expose store-specific extensions of these base interfaces to allow access to store-specific functionality like flushing or dedicated batching that take some store specifics into account. An example for this is deleteInBatch(…) of JpaRepository which is different from delete(…) as it uses a query to delete the given entities which is more performant but comes with the side effect of not triggering the JPA-defined cascades (as the spec defines it).
我们通常建议不要使用这些基本接口,因为它们将底层持久性技术暴露给客户机,从而加强了客户机与存储库之间的耦合。另外,您还偏离了存储库的原始定义,它基本上是“实体的集合”。所以如果可以,请使用PagingAndSortingRepository。
自定义存储库基础接口
直接依赖于所提供的基本接口的缺点有两个。它们都可能被认为是理论性的,但我认为了解它们很重要:
Depending on a Spring Data repository interface couples your repository interface to the library. I don't think this is a particular issue as you'll probably use abstractions like Page or Pageable in your code anyway. Spring Data is not any different from any other general purpose library like commons-lang or Guava. As long as it provides reasonable benefit, it's just fine. By extending e.g. CrudRepository, you expose a complete set of persistence method at once. This is probably fine in most circumstances as well but you might run into situations where you'd like to gain more fine-grained control over the methods expose, e.g. to create a ReadOnlyRepository that doesn't include the save(…) and delete(…) methods of CrudRepository.
解决这两个缺点的方法是创建自己的基本存储库接口,甚至是一组基础存储库接口。在很多应用中,我看到过这样的东西:
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…(…)方法,但不公开操作方法。在参考文档中阅读关于该方法的更多信息。
摘要- tl
存储库抽象允许您选择完全由您的架构和功能需求驱动的基本存储库。如果合适的话,使用现成提供的接口,如果必要的话,制作自己的存储库基础接口。除非不可避免,否则不要使用特定于存储库的接口。