JpaRepository 扩展自 PagingAndSortingRepository,而 PagingAndSortingRepository 又扩展自 CrudRepository。
它们的主要功能如下:
CrudRepository 提供了CRUD(增删改查)函数。PagingAndSortingRepository 提供将记录进行分页和排序的方法。JpaRepository 提供了一些与 JPA 相关的方法,例如刷新持久化上下文并批量删除记录。由于上述继承关系,JpaRepository 将具有 CrudRepository 和 PagingAndSortingRepository 提供的所有功能。因此,如果您不需要存储库具有 JpaRepository 和 PagingAndSortingRepository 提供的功能,请使用 CrudRepository。
肯的答案基本正确,但我想在你问题中的“为什么要使用其中之一?”方面发表一下意见。
您选择的存储库的基本接口具有两个主要目的。首先,允许Spring Data存储库基础设施找到您的接口并触发代理创建,以便将接口实例注入客户端。第二个目的是将所需功能尽可能多地引入接口,而无需声明额外的方法。
Spring Data核心库附带了两个基础接口,公开了一组专用功能:
CrudRepository - CRUD方法PagingAndSortingRepository - 分页和排序方法(扩展CrudRepository)各个存储模块(例如JPA或MongoDB)公开了这些基础接口的存储特定扩展,以允许访问存储特定功能,如考虑某些存储细节的刷新或专用批处理。其中一个示例是JpaRepository的deleteInBatch(…),它与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
}
第一个仓库接口是一些通用基础接口,实际上只修复了第一点,但也将ID类型绑定为Long以保持一致性。第二个接口通常从CrudRepository和PagingAndSortingRepository中复制所有find…(…)方法,但不公开操纵这些方法。在参考文档中阅读更多有关该方法的信息。
简而言之,仓库抽象允许您完全根据架构和功能需求选择基础存储库。如果适合,使用提供的默认存储库,如果必要,请自定义存储库基础接口。除非不可避免,否则请远离特定于存储的存储库接口。
摘要:
PagingAndSortingRepository 扩展自 CrudRepository
JpaRepository 扩展自 PagingAndSortingRepository
CrudRepository 接口提供了 CRUD(增删改查)操作的方法,因此它允许您在不定义自己的方法的情况下创建、读取、更新和删除记录。
PagingAndSortingRepository 提供了使用分页和排序检索实体的其他方法。
最后,JpaRepository 添加了一些特定于 JPA 的功能。
CrudRepository和JpaRepository之间的区别:
CrudRepositoryCrudRepository是一个基础接口,继承了Repository接口。CrudRepository主要提供CRUD(创建、读取、更新、删除)操作。saveAll()方法的返回类型为Iterable。CrudRepository的存储库以执行CRUD操作。JpaRepositoryJpaRepository扩展了PagingAndSortingRepository,后者又扩展了CrudRepository。JpaRepository提供了CRUD和分页操作,还提供了其他方法,如flush()、saveAndFlush()和deleteInBatch()等。saveAll()方法的返回类型为List。JpaRepository的存储库以执行CRUD和批量操作。spring-data-jpa 3.x从现在开始使用spring-boot 3.x和spring-core 6.x与spring-data-jpa 3.x,结构和层次结构已经修改,看起来更清晰。
ListCrudRepository扩展了CrudRepository
ListPagingAndSortingRepository扩展PagingAndSortingRepository
JpaRepository同时扩展了ListCrudRepository和ListPagingAndSortingRepository。
因此,基本上ListPagingAndSortingRepository和ListCrudRepository这两个新引入的接口现在代表旧接口的功能,但返回类型为List<T>,而剩余的PagingAndSortingRepository和CrudRepository则处理Iterable<T>类型的返回值。
在新版本(3.x)中,结构如下:
在过去(3.0之前),许多声明返回List<T>的方法直接在JpaRepository中声明,但现在这些方法已被提取到ListPagingAndSortingRepository和ListCrudRepository中。
因此,在3.x版本之前的结构如下:
我希望从上面的图表中清楚地了解如何在3.x版本中修改所提到的JpaRepository和CrudRepository。
2.x 版本迁移到 3.x 版本(如果您从 spring-boot 2.x 迁移到 spring-boot 3.x,则必须这样做),如上图所示,您应该预期在您的代码中使用了 PagingAndSortingRepository 的情况下会有破坏性代码,因为过去它是从 CrudRepository 继承的,因此直接扩展 PagingAndSortingRepository 的自定义存储库已经能够访问 CrudRepository 的方法。如果出现此问题,您应该通过调整自定义存储库以扩展 ListCrudRepository 或 CrudRepository 来解决此问题。
所有答案都提供了足够的细节来回答问题。但是,让我添加更多的内容。
为什么要使用这些接口:
每个接口的作用:
何时使用哪个接口:
根据 http://jtuts.com/2014/08/26/difference-between-crudrepository-and-jparepository-in-spring-data-jpa/
通常最好根据是否需要排序和分页来使用 CrudRepository 或 PagingAndSortingRepository 。
如果可能的话,应该避免使用JpaRepository,因为它将您的存储库与JPA持久性技术绑定在一起,在大多数情况下,您可能甚至不会使用它提供的额外方法。
Spring Data JPA提供了JpaRepository和CrudRepository接口,以简化JPA应用程序中数据访问库的创建。
CrudRepository是具有基本CRUD(创建、读取、更新、删除)操作的实体的基本接口。CrudRepository提供了一组最小的方法,如save()、findAll()、findById()、delete()等,并可以通过其他自定义方法进行扩展。
这是代码示例:
public interface PersonEntityRepository extends CrudRepository<PersonEntity, Long> {
}
JpaRepository 接口扩展了 CrudRepository 接口。
JpaRepository 接口提供了其他基本 CRUD 操作之外的附加方法,例如:
findAll(Sort sort) - 返回按给定条件排序的所有实体的方法。findAll(Pageable pageable) - 根据给定的分页和排序条件返回一个实体页面的方法。flush() - 将所有待处理更改刷新到数据库的方法。saveAndFlush(T entity) - 保存实体并立即将更改刷新到数据库的方法。
这是代码示例:public interface PersonEntityRepository extends JpaRepository<PersonEntity, Long> {
List<TestEntity> findByName(String name);
List<Employee> findByAgeGreaterThan(double age);
}
你为什么要选择一个而不是另一个?
选择哪个取决于你的应用程序的具体需求。我建议使用 CrudRepository 接口进行基本的 CRUD 操作,使用 JpaRepository 接口进行更高级的功能,如分页、排序和立即将更改刷新到数据库。
Crud Repository是基础接口,充当标记接口。
JPA repository也扩展了PagingAndSorting repository。它提供了所有有用于实现分页的方法。Crud Repository不提供实现分页和排序的方法。
CrudRepository 不是一个标记接口。在代码中也很少(可能为0)检查它的实例,因此它也不起到标记接口的作用。 - Jens Schauder