Spring Data Commons 的 Page 接口提供了一种统一的机制来表示和处理分页数据,无论底层数据源是什么。Page 接口抽象了分页的详细信息,如页码、页面大小和总元素数,并提供了便捷的方法来操作和遍历分页数据。这使得 Spring Data 中的所有存储库都可以统一地处理分页,同时保持与底层数据源的不可知性。

Core concepts

Spring Data 存储库抽象中的中心接口是 Repository。它取管理的领域类以及作为类型参数的领域类的标识符类型。此接口主要充当标记接口,用于捕获要处理的类型,并帮助你发现扩展此接口的接口。https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html[CrudRepository] 和 ListCrudRepository 接口提供被管理的实体类的复杂 CRUD 功能。

The central interface in the Spring Data repository abstraction is Repository. It takes the domain class to manage as well as the identifier type of the domain class as type arguments. This interface acts primarily as a marker interface to capture the types to work with and to help you to discover interfaces that extend this one. The CrudRepository and ListCrudRepository interfaces provide sophisticated CRUD functionality for the entity class that is being managed.

CrudRepository Interface
public interface CrudRepository<T, ID> extends Repository<T, ID> {

  <S extends T> S save(S entity);      1

  Optional<T> findById(ID primaryKey); 2

  Iterable<T> findAll();               3

  long count();                        4

  void delete(T entity);               5

  boolean existsById(ID primaryKey);   6

  // … more functionality omitted.
}
1 Saves the given entity.
2 Returns the entity identified by the given ID.
3 Returns all entities.
4 Returns the number of entities.
5 Deletes the given entity.
6 Indicates whether an entity with the given ID exists.

在此接口中声明的方法通常称为 CRUD 方法。ListCrudRepository 提供等效方法,但它们在 CrudRepository 方法返回 Iterable 的位置返回 List

The methods declared in this interface are commonly referred to as CRUD methods. ListCrudRepository offers equivalent methods, but they return List where the CrudRepository methods return an Iterable.

我们还提供了特定于持久化技术的抽象,例如 JpaRepositoryMongoRepository。这些接口扩展了 CrudRepository,除了相当通用的与持久化技术无关的接口(例如 CrudRepository)之外,还公开了底层持久化技术的功能。

We also provide persistence technology-specific abstractions, such as JpaRepository or MongoRepository. Those interfaces extend CrudRepository and expose the capabilities of the underlying persistence technology in addition to the rather generic persistence technology-agnostic interfaces such as CrudRepository.

除了 CrudRepository 之外,还有 PagingAndSortingRepositoryListPagingAndSortingRepository,它们添加了更多方法,可以轻松地对实体进行分页访问:

Additional to the CrudRepository, there are PagingAndSortingRepository and ListPagingAndSortingRepository which add additional methods to ease paginated access to entities:

PagingAndSortingRepository interface
public interface PagingAndSortingRepository<T, ID>  {

  Iterable<T> findAll(Sort sort);

  Page<T> findAll(Pageable pageable);
}

扩展接口受实际存储模块支持。虽然此文档解释了通用方案,但请确保您的存储模块支持您想要使用的接口。

Extension interfaces are subject to be supported by the actual store module. While this documentation explains the general scheme, make sure that your store module supports the interfaces that you want to use.

要按页面大小 20 访问 User 的第二页,可以执行以下操作:

To access the second page of User by a page size of 20, you could do something like the following:

PagingAndSortingRepository<User, Long> repository = // … get access to a bean
Page<User> users = repository.findAll(PageRequest.of(1, 20));

ListPagingAndSortingRepository 提供等效方法,但返回 List,而 PagingAndSortingRepository 方法返回 Iterable

ListPagingAndSortingRepository offers equivalent methods, but returns a List where the PagingAndSortingRepository methods return an Iterable.

除了查询方法外,还可以使用计数查询和删除查询的查询派生。以下列表显示派生计数查询的接口定义:

In addition to query methods, query derivation for both count and delete queries is available. The following list shows the interface definition for a derived count query:

Derived Count Query
interface UserRepository extends CrudRepository<User, Long> {

  long countByLastname(String lastname);
}

以下列表显示派生删除查询的接口定义:

The following listing shows the interface definition for a derived delete query:

Derived Delete Query
interface UserRepository extends CrudRepository<User, Long> {

  long deleteByLastname(String lastname);

  List<User> removeByLastname(String lastname);
}