1、概览 {#1概览}
当我们数据库中的记录数量较多的时候,一般不会一次性检索出所有记录,通常会通过分页的方式展现。
此外,我们还经常需要在分页时根据某些条件对数据进行排序。
在本教程中,我们将学习如何使用 Spring Data JPA 轻松实现分页和排序。
2、创建实体 {#2创建实体}
首先,假设我们有一个 Product
实体作为 domain 类:
@Entity
public class Product {
@Id
private long id;
private String name;
private double price;
// 构造函数, getter 和 setter
}
我们的每个 Product
实例都有一个唯一的标识符: id
、name
和 price
。
3、创建 Repository {#3创建-repository}
要访问我们的 Product
,我们需要一个 ProductRepository
:
public interface ProductRepository extends PagingAndSortingRepository<Product, Integer> {
List<Product> findAllByPrice(double price, Pageable pageable);
}
通过让它继承 PagingAndSortingRepository,我们可以使用,用于分页和排序的 findAll(Pageable pageable)
和 findAll(Sort sort)
方法。
相反,我们也可以选择继承 JpaRepository
,因为它也继承了 PagingAndSortingRepository
。
一旦我们继承了 PagingAndSortingRepository
,我们就可以添加自己的方法,使用 Pageable
和 Sort
作为参数,就像上面代码中的 findAllByPrice
一样。
让我们看看如何使用新方法对 Product
进行分页检索。
4、分页 {#4分页}
一旦我们的 repository 继承了 PagingAndSortingRepository
,那么我们只需要:
- 创建或获取
PageRequest
对象,它是Pageable
接口的一个实现。 - 将
PageRequest
对象作为参数传递给我们打算使用的 repository 方法。
我们可以通过如下方式指定"页数"和"每页记录数量"来创建 PageRequest
对象。
注意,页数从 0 开始:
Pageable firstPageWithTwoElements = PageRequest.of(0, 2);
Pageable secondPageWithFiveElements = PageRequest.of(1, 5);
在 Spring MVC 中,我们还可以选择使用 Spring Data Web Support 在 controller 中获取 Pageable
实例。
有了 PageRequest
对象后,我们就可以在调用 repository 方法时将其传入:
Page<Product> allProducts = productRepository.findAll(firstPageWithTwoElements);
List<Product> allTenDollarProducts =
productRepository.findAllByPrice(10, secondPageWithFiveElements);
findAll(Pageable pageable)
方法默认返回一个 Page<T>
对象。
不过,我们也可以选择从任何返回分页数据的自定义方法中返回 Page<T>
、Slice<T>
或 List<T>
。 Page<T>
实例除了有 Product
列表外,还有总页数。为此,它会触发额外的 COUNT
查询。为了避免这种开销,我们可以直接返回一个 Slice<T>
或 List<T>
。
Slice
不知道总记录数量,它只知道是否还有下一个 slice。
5、分页和排序 {#5分页和排序}
同样,如果只想对查询结果进行排序,我们只需向该方法传递一个 Sort
的实例即可:
Page<Product> allProductsSortedByName = productRepository.findAll(Sort.by("name"));
但是,如果我们想在分页的时候同时进行排序呢?
我们可以通过将排序的细节传递给 PageRequest
对象来实现:
Pageable sortedByName =
PageRequest.of(0, 3, Sort.by("name"));
Pageable sortedByPriceDesc =
PageRequest.of(0, 3, Sort.by("price").descending());
Pageable sortedByPriceDescNameAsc =
PageRequest.of(0, 5, Sort.by("price").descending().and(Sort.by("name")));
根据排序需求,我们可以在创建 PageRequest
实例时指定排序字段和排序方向。
像一般用法一样,我们可以将这个 Pageable
类型实例传递给 repository 的方法。
6、总结 {#6总结}
在本文中,我们学习了如何在 Spring Data JPA 中对查询结果进行分页和排序。
参考:https://www.baeldung.com/spring-data-jpa-pagination-sorting