查看原文
其他

使用 Spring Data JPA 进行分页和排序

Darren Luo SpringForAll社区 2020-10-17

了解如何使用 Spring Data JPA 实现分页和排序。

概览

当处理大量数据时,延迟处理通常是必不可少的。即使服务返回大量数据,消费者也不太可能使用它。想象一个购物网站,客户在网站上搜索产品,网站有数千种产品可供展示。获取数千种产品并将他们显示网页上将非常耗时。在大多数情况下,客户甚至可能不会查看所有产品。

对于这种情况,一种被叫做分页的技术被使用了。首先只显示一小部分产品(页面),客户可以要求查看下一部分(页面)等。

要了解 JPA 和 Spring Data JPA 的基础知识,请查看以下链接:

  • Hands-on Spring Data JPA (A Spring Data JPA Learning Series)

  • What is JPA, Spring Data and Spring Data JPA

实体(Entity)

为了本教程的目的,我们将考虑 Employee 实体的最简单实例。下面是 Employee实体类。

  1. @Entity

  2. public class Employee {

  3. @Id

  4. private Long name;


  5. private String firstName;

  6. private String lastName;

  7. private Date dateOfBirth;

  8. private Integer age;

  9. private String designation;

  10. private double salary;

  11. private Date dateOfJoining;


  12. public Long getName() {

  13. return name;

  14. }


  15. public void setName(Long name) {

  16. this.name = name;

  17. }


  18. public String getFirstName() {

  19. return firstName;

  20. }


  21. public void setFirstName(String firstName) {

  22. this.firstName = firstName;

  23. }


  24. public String getLastName() {

  25. return lastName;

  26. }


  27. public void setLastName(String lastName) {

  28. this.lastName = lastName;

  29. }


  30. public Date getDateOfBirth() {

  31. return dateOfBirth;

  32. }


  33. public void setDateOfBirth(Date dateOfBirth) {

  34. this.dateOfBirth = dateOfBirth;

  35. }


  36. public Integer getAge() {

  37. return age;

  38. }


  39. public void setAge(Integer age) {

  40. this.age = age;

  41. }


  42. public String getDesignation() {

  43. return designation;

  44. }


  45. public void setDesignation(String designation) {

  46. this.designation = designation;

  47. }


  48. public double getSalary() {

  49. return salary;

  50. }


  51. public void setSalary(double salary) {

  52. this.salary = salary;

  53. }


  54. public Date getDateOfJoining() {

  55. return dateOfJoining;

  56. }


  57. public void setDateOfJoining(Date dateOfJoining) {

  58. this.dateOfJoining = dateOfJoining;

  59. }

  60. }

想了解更多关于在 Spring 和 Spring Boot 中使用 Java 持久化 API (JPA)的信息?

查看一下附加链接:

  • Spring Boot with Spring Data JPA

  • Spring Data JPA Composite Key with @EmbeddedId

  • Spring Data JPA find by @EmbeddedId Partially

  • Java Persistence API Guide

  • Spring Data JPA Query Methods

Employee 存储库(Repository)

在文章《Spring Data JPA Query Methods》中,我们已经了解了 Spring 存储库接口和查询方法。这里,我们需要学习分页,所以我们将使用 Spring 的 PagingAndSortingRepository

  1. @Repository

  2. public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long> {


  3. Page<Employee> findAll(Pageable pageable);


  4. Page<Employee> findByFirstName(String firstName, Pageable pageable);


  5. Slice<Employee> findByFirstNameAndLastName(String firstName, String lastName, Pageable pageable);

  6. }

分页(Pagination)

看一看 EmployeeRepository。该方法接受 Pageable 参数。 Pageable 是一个由 Spring 定义的接口,它拥有一个 PageRequest。让我们看看如何创建一个 PageRequest

  1. Pageable pageable = PageRequest.of(0, 10);

  2. Page<Employee> page = employeeRepository.findAll(pageable);

在第一行,我们创建了一个 10 个员工的 PageRequest,并请求第一页(0)。该页面请求被传递给 findAll 以获取 Employee 的页面作为响应。

如果我们要访问下一页,我们可以每次增加页码。

  1. PageRequest.of(1, 10);

  2. PageRequest.of(2, 10);

  3. PageRequest.of(3, 10);

  4. ...

排序

Spring Data JPA 提供了一个 Sort 对象以提供排序机制。让我们看看排序的方式。

  1. employeeRepository.findAll(Sort.by("fistName"));


  2. employeeRepository.findAll(Sort.by("fistName").ascending().and(Sort.by("lastName").descending());

显然,第一个按“firstName”简单的排序,另一个按“firstName”升序和“lastName”降序排序。

同时分页和排序

  1. Pageable pageable = PageRequest.of(0, 20, Sort.by("firstName"));


  2. Pageable pageable = PageRequest.of(0, 20, Sort.by("fistName").ascending().and(Sort.by("lastName").descending());

切片(Slice) Vs. 页(Page)

EmployeeRepository 中,我们看到其中一个方法返回 Slice,另一个返回 Page。它们都是 Spring Data JPAPageSlice 的子接口。他们都用于保存并返回数据的子集。让我们一个一个看看它们。

分片(Slice)

Slice 知道它是否有内容以及它是否是第一个或最后一个分片。它还能够返回当前和之前分片使用的 Pageable。我们来看看 Slice 的一些重要方法。

  1. List<T> getContent(); // get content of the slice


  2. Pageable getPageable(); // get current pageable


  3. boolean hasContent();


  4. boolean isFirst();


  5. boolean isLast();


  6. Pageable nextPageable(); // pageable of the next slice


  7. Pageable previousPageable(); // pageable of the previous slice

页(Page)

PageSlice 的子接口并有几个额外的方法。它知道表中的总页数以及记录总数。以下是 Page 的一些重要方法。

  1. static <T> Page<T> empty; //create an empty page


  2. long getTotalElements(); // number of total elements in the table


  3. int totalPages() // number of total pages in the table

总结

在使用 Spring Data JPA 的分页和排序示例中,我们了解了为什么需要分页。我们还学习了如何获取分页以及排序的数据子集。最后,我们也看了 SlicePage 接口以及他们的区别。

在这里阅读原始帖子:Pagination and Sorting with Spring Data JPA。

原文链接:https://dzone.com/articles/pagination-and-sorting-with-spring-data-jpa

作者:Amit Phaltankar

译者:Darren Luo

推荐: Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现

上一篇:Spring Boot:一件艺术品



 关注公众号

点击原文阅读更多


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存