在本教程中,我将向您展示如何使用带有自定义查询的 Spring 数据分页来实现 Spring 引导分页。
Pageable
接口包含有关所请求页面的信息,例如大小、页面编号或Sort对象
排序信息。
public interface Pageable {
int getPageNumber();
int getPageSize();
long getOffset();
Sort getSort();
Pageable next();
Pageable previousOrFirst();
Pageable first();
boolean hasPrevious();
...
}
因此,当我们想在结果中进行分页和排序(带或不带过滤器)时,我们只需将方法的定义添加Pageable
参数。
这就是我们使用实现Pageable
接口的PageRequest类创建Pageable
对象的方式:
Pageable paging = PageRequest.of(page, size, sort);
page
:从零开始的页面索引,不得为负数。size
:页面中要返回的项目数必须大于 0。sort
:Sort
对象。Spring Data 还支持许多有用的从方法名称创建查询(派生查询),我们将使用这些方法名称来过滤此示例中的结果,例如:
Page findByPublished(boolean published, Pageable pageable);
Page findByTitleContaining(String title, Pageable pageable);
有关更多详细信息,请访问:
Spring Boot 中的 Spring JPA 派生查询示例
让我们注意上面存储库方法中的可分页参数。Spring 数据基础设施将自动识别此参数,以将分页和排序应用于数据库。
那么,如何将自定义查询与 Spring 数据分页一起使用呢?
让我们来探索一下。
在模型包中,我们定义Tutorial
类。
教程有六个字段:id、标题、级别、描述、发布、创建于。
model/Tutorial.java
package com.bezkoder.spring.query.model;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "tutorials")
public class Tutorial {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String title;
private String description;
private int level;
private boolean published;
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
public Tutorial() {
}
public Tutorial(String title, String description, int level, boolean published, Date createdAt) {
this.title = title;
this.description = description;
this.level = level;
this.published = published;
this.createdAt = createdAt;
}
// getters and setters
}
@Entity
–注释表示该类是持久性 Java 类。
@Table
–注释提供映射此实体的表。
@Id
–注释用于主键。@GeneratedValue
–注释用于定义主键的生成策略。
@Temporal
–注释在时间戳和java.util.Date
或时间戳之间来回转换到时间。例如,@Temporal(TemporalType.DATE)
删除时间值并仅保留日期。
@Temporal(TemporalType.DATE)
private Date createdAt;
让我们创建一个存储库来与数据库进行交互。
在存储库包中,创建扩展JpaRepository
接口的TutorialRepository
。
repository/TutorialRepository.java
package com.bezkoder.spring.query.repository;
import com.bezkoder.spring.query.model.Tutorial;
public interface TutorialRepository extends JpaRepository {
}
在此接口中,我们将编写 JPA 自定义查询(带有 where 条件)以从数据库中获取数据。
我将向您展示如何使用Pageable进行
JPQL查询和本机查询。
假设我们已经有了这样的教程表:
Spring Data JPA 查询示例使用Pageable
类进行分页(具有排序和过滤):
@Query("SELECT t FROM Tutorial t")
Page findAllWithPagination(Pageable pageable);
@Query("SELECT t FROM Tutorial t WHERE t.published=?1")
Page findByPublishedWithPagination(boolean isPublished, Pageable pageable);
@Query("SELECT t FROM Tutorial t WHERE LOWER(t.title) LIKE LOWER(CONCAT('%', ?1,'%'))")
Page findByTitleWithPagination(String title, Pageable pageable);
结果:
int page = 0;
int size = 3;
Pageable pageable = PageRequest.of(page, size);
tutorials = tutorialRepository.findAllWithPagination(pageable).getContent();
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Tut#1 Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=2, title=Java Spring, description=Tut#2 Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Tut#3 Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
*/
pageable = PageRequest.of(page, size, Sort.by("level").descending());
tutorials = tutorialRepository.findAllWithPagination(pageable).getContent();
show(tutorials);
/*
Tutorial [id=7, title=Spring Security, description=Tut#7 Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Tut#6 Description, level=4, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=5, title=Spring Data JPA, description=Tut#5 Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
*/
pageable = PageRequest.of(page, size);
tutorials = tutorialRepository.findByTitleWithPagination("ring", pageable).getContent();
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Tut#1 Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=2, title=Java Spring, description=Tut#2 Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Tut#4 Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
*/
pageable = PageRequest.of(page, size, Sort.by("level").descending());
tutorials = tutorialRepository.findByPublishedWithPagination(false, pageable).getContent();
show(tutorials);
/*
Tutorial [id=7, title=Spring Security, description=Tut#7 Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Tut#6 Description, level=4, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Tut#4 Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
*/
Spring Data JPA 本机查询示例使用Pageable
类进行分页(带有排序和过滤):
@Query(value = "SELECT * FROM tutorials", nativeQuery = true)
Page findAllWithPagination(Pageable pageable);
@Query(value = "SELECT * FROM tutorials t WHERE t.published=?1", nativeQuery = true)
Page findByPublished(boolean isPublished, Pageable pageable);
@Query(value = "SELECT * FROM tutorials t WHERE LOWER(t.title) LIKE LOWER(CONCAT('%', ?1,'%'))", nativeQuery = true)
Page findByTitleLike(String title, Pageable pageable);
结果:
int page = 0;
int size = 3;
Pageable pageable = PageRequest.of(page, size);
tutorials = tutorialRepository.findAllWithPagination(pageable).getContent();
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Tut#1 Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=2, title=Java Spring, description=Tut#2 Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Tut#3 Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
*/
pageable = PageRequest.of(page, size, Sort.by("level").descending());
tutorials = tutorialRepository.findAllWithPagination(pageable).getContent();
show(tutorials);
/*
Tutorial [id=7, title=Spring Security, description=Tut#7 Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Tut#6 Description, level=4, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=5, title=Spring Data JPA, description=Tut#5 Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
*/
pageable = PageRequest.of(page, size);
tutorials = tutorialRepository.findByTitleLike("ring", pageable).getContent();
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Tut#1 Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=2, title=Java Spring, description=Tut#2 Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Tut#4 Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
*/
pageable = PageRequest.of(page, size, Sort.by("level").descending());
tutorials = tutorialRepository.findByPublished(false, pageable).getContent();
show(tutorials);
/*
Tutorial [id=7, title=Spring Security, description=Tut#7 Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Tut#6 Description, level=4, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Tut#4 Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
*/
今天,我们已经知道如何在 Spring Boot 示例中使用 JPQL 和本机查询将 Spring Data JPA Pageable 与自定义查询一起使用。