Spring Boot JPA 存储库派生查询示例

news2025/1/23 13:18:25

在之前的文章中,您已经知道如何使用JPQL和本机查询通过注释从数据库中检索数据。今天,我将向您展示如何使用派生查询方法在 Spring 引导中实现 Spring Data JPA 存储库查询:@Query

  • 派生查询方法的结构
  • 配置 Spring 引导应用程序以使用不同的数据库
  • JPA 按字段、列名、多列查找
  • 用于分页和排序的 JPA 查询方法

内容

  • 派生查询方法的结构
  • 使用 Spring 引导的 JPA 存储库查询示例
  • 创建和设置 Spring Boot 项目
  • 配置 Spring 数据源、JPA、Hibernate
  • 创建实体
  • 定义 JPA 存储库查询方法
  • 按字段查找 JPA
  • 通过多个列查找 JPA
  • JPA 喜欢查询
  • JPA 布尔查询
  • 带比较的 JPA 存储库查询
  • 带排序的 JPA 存储库查询
  • 带分页的 JPA 存储库查询
  • 具有分页和排序功能的 JPA 存储库查询
  • JPA 删除多行
  • 运行 Spring JPA 派生查询项目
  • 结论
  • 延伸阅读
  • 源代码

派生查询方法的结构

通常,派生查询方法具有 2 个元素:主语(操作)和谓词(条件)。

  • 主语:是引入子句(,,例如),它可能包含结果限制关键字(如 asor/)的进一步表达式(介于//和之间)。find…Byexists…Bycount…ByfindexistscountByDistinctTopFirst
  • 谓语:放在主语之后。它可以是实体属性(与 / 连接),后跟一个或多个关键字 (,,,...)。AndOrStartingWithEndingWithContainingIgnoreCase

例如:

<span style="color:#000000"><span style="background-color:#fafafa !important"><code class="language-java"><span style="color:#000000">List</span><span style="color:#999999"><</span><span style="color:#000000">Tutorial</span><span style="color:#999999">></span> <span style="color:#dd4a68">findByTitleContainingIgnoreCase</span><span style="color:#999999">(</span><span style="color:#000000">String</span> title<span style="color:#999999">)</span><span style="color:#999999">;</span>

<span style="color:#000000">List</span><span style="color:#999999"><</span><span style="color:#000000">Tutorial</span><span style="color:#999999">></span> <span style="color:#dd4a68">findTop3ByTitleContainingAndPublished</span><span style="color:#999999">(</span><span style="color:#000000">String</span> title<span style="color:#999999">,</span> <span style="color:#0077aa">boolean</span> isPublished<span style="color:#999999">)</span><span style="color:#999999">;</span>
</code></span></span>

您可以在查询方法主题关键字和查询方法谓词关键字中找到完整列表。

使用 Spring 引导的 JPA 存储库查询示例

–科技:

  • 爪哇 8
  • Spring Boot 2.6.3 (带有 Spring Data JPA)
  • MySQL/PostgreSQL/H2 (嵌入式数据库)
  • Maven 3.8.1

– 项目结构:

让我简要解释一下。

 

  • Tutorial数据模型类对应于实体和表教程
  • TutorialRepository是一个为派生查询方法扩展JpaRepository的接口。它将被自动连接。SpringBootQueryExampleApplication
  • SpringBootQueryExampleApplication是哪个实现。我们将在这里运行查询方法。SpringBootApplicationCommandLineRunnerTutorialRepository
  • application.properties中配置Spring Datasource,JPA和Hibernate。
  • pom.xml包含 Spring Boot 和 MySQL/PostgreSQL/H2 数据库的依赖项。

创建和设置 Spring Boot 项目

使用 Spring Web 工具或您的开发工具(Spring Tool Suite、Eclipse、Intellij)创建 Spring Boot 项目。

然后打开pom.xml并添加以下依赖项:

<!-- web for access H2 database UI -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

我们还需要再添加一个依赖项。
如果你想使用MySQL

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

– 或PostgreSQL

<dependency>
	<groupId>org.postgresql</groupId>
	<artifactId>postgresql</artifactId>
	<scope>runtime</scope>
</dependency>

– 或H2(嵌入式数据库):

<dependency>
	<groupId>com.h2database</groupId>
	<artifactId>h2</artifactId>
	<scope>runtime</scope>
</dependency>

配置 Spring 数据源、JPA、Hibernate

在 src/main/resources 文件夹下,打开 application.properties 并编写这些行。

– 对于 MySQL:

spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false
spring.datasource.username= root
spring.datasource.password= 123456

spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update

对于PostgreSQL:

spring.datasource.url= jdbc:postgresql://localhost:5432/testdb
spring.datasource.username= postgres
spring.datasource.password= 123

spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation= true
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.PostgreSQLDialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update
  • spring.datasource.username & spring.datasource.password属性与数据库安装相同。
  • Spring Boot 使用 Hibernate 进行 JPA 实现,我们配置 MySQL 或 PostgreSQLMySQL5InnoDBDialectPostgreSQLDialect
  • spring.jpa.hibernate.ddl-auto用于数据库初始化。我们将值设置为值,以便在数据库中自动创建一个与定义的数据模型对应的表。对模型的任何更改也将触发对表的更新。对于生产,此属性应该是。updatevalidate

– 对于 H2 数据库:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
 
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto= update

spring.h2.console.enabled=true
# default path: h2-console
spring.h2.console.path=/h2-ui
  • spring.datasource.url:用于内存数据库和基于磁盘的数据库。jdbc:h2:mem:[database-name]jdbc:h2:file:[path/database-name]
  • 我们为 H2 数据库配置配置H2Dialect
  • spring.h2.console.enabled=true告诉 Spring 启动 H2 数据库管理工具,您可以在浏览器上访问此工具:http://localhost:8080/h2-console
  • spring.h2.console.path=/h2-ui用于 H2 控制台的 URL,因此默认 url 将更改为。http://localhost:8080/h2-consolehttp://localhost:8080/h2-ui

创建实体

模型包中,我们定义类。Tutorial

教程具有以下字段:id、标题、级别、描述、已发布、创建于。

模型/教程.java

package com.bezkoder.spring.jpa.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;

定义 JPA 存储库查询方法

让我们创建一个存储库来与数据库进行交互。
存储库包中,创建扩展的接口。TutorialRepositoryJpaRepository

存储库/教程存储库.java

package com.bezkoder.spring.jpa.query.repository;

import com.bezkoder.spring.jpa.query.model.Tutorial;

public interface TutorialRepository extends JpaRepository<Tutorial, Long> {

}

在此接口中,我们将编写 JPA 派生查询以从数据库中获取数据。

假设我们已经有了这样的教程表:

 

让我们检查一下基本的查询方法:首先findAll()

public interface TutorialRepository extends JpaRepository<Tutorial, Long> {
  List<Tutorial> findAll();
}

结果:

List<Tutorial> tutorials = new ArrayList<>();

tutorials = tutorialRepository.findAll();
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

按字段查找 JPA

我们只需要在后面附加字段,然后在派生查询上添加 bothor关键字以提高可读性(可选)。byIsEquals

Optional<Tutorial> findById(long id);

List<Tutorial> findByLevel(int level);

List<Tutorial> findByPublished(boolean isPublished);

List<Tutorial> findByLevelIs(int level);

List<Tutorial> findByLevelEquals(int level);

结果:

Tutorial tutorial = tutorialRepository.findById(1).get();
System.out.println(tutorial);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
*/

tutorials = tutorialRepository.findByPublished(true);
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
*/

tutorials = tutorialRepository.findByLevel(3);
// or
tutorials = tutorialRepository.findByLevelIs(3);
// or
tutorials = tutorialRepository.findByLevelEquals(3);
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
*/

相反,您可以使用或关键字。NotIsNot

List<Tutorial> findByLevelNot(int level);

List<Tutorial> findByLevelIsNot(int level);

结果:

tutorials = tutorialRepository.findByLevelNot(3);
// or
tutorials = tutorialRepository.findByLevelIsNot(3);
show(tutorials);
/*
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

通过多个列查找 JPA

对于多个字段/多个列,我们可以使用字段/列之间的关键字。
请注意,您可以根据需要连接任意数量/任意数量。AndOrAndOr

List<Tutorial> findByLevelAndPublished(int level, boolean isPublished);

List<Tutorial> findByTitleOrDescription(String title, String description);

结果:

tutorials = tutorialRepository.findByLevelAndPublished(3, true);
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
*/

tutorials = tutorialRepository.findByTitleOrDescription("Hibernate", "Spring Data Description");
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
*/

JPA 喜欢查询

我们可以使用以下关键字执行 SQL LIKE 查询:

  • Like:其中 x.字段像参数
  • NotLike:其中 x.field 不像参数
  • StartingWith:其中 x.field 像 %param (附加%)
  • EndingWith:其中 x.field 像参数百分比(带有前缀%)
  • Containing:其中 x.field 像 %param% (括在 %)
List<Tutorial> findByTitleLike(String title);

List<Tutorial> findByTitleStartingWith(String title);

List<Tutorial> findByTitleEndingWith(String title);

List<Tutorial> findByTitleContaining(String title);

List<Tutorial> findByTitleContainingOrDescriptionContaining(String title, String description);

List<Tutorial> findByTitleContainingAndPublished(String title, boolean isPublished);

对于不区分大小写的查询,在 SQL 中,我们可以强制将值强制为全部大写或小写字母,然后与查询值进行比较。
Spring JPA 提供了关键字来使用派生查询来执行此操作。IgnoreCase

List<Tutorial> findByTitleContainingIgnoreCase(String title);

结果:

tutorials = tutorialRepository.findByTitleStartingWith("Spring");
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

tutorials = tutorialRepository.findByTitleEndingWith("ot");
show(tutorials);
/*
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
*/

tutorials = tutorialRepository.findByTitleContaining("at");
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
*/

tutorials = tutorialRepository.findByTitleContainingIgnoreCase("dat");
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
*/

String text = "ot";
tutorials = tutorialRepository.findByTitleContainingOrDescriptionContaining(text, text);
show(tutorials);
/*
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
*/

tutorials = tutorialRepository.findByTitleContainingAndPublished("ring", true);
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
*/

JPA 布尔查询

我们可以使用关键字来制作 JPA 布尔派生查询。TrueFalse

List<Tutorial> findByPublishedTrue();

List<Tutorial> findByPublishedFalse();

结果:

tutorials = tutorialRepository.findByPublishedTrue();
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
*/

tutorials = tutorialRepository.findByPublishedFalse();
show(tutorials);
/*
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

带比较的 JPA 存储库查询

我们可以使用以下关键字执行 SQL 比较查询:

  • Between:其中 x.字段介于 param_1 和 param_2 之间
  • LessThan:其中 x.field <参数
  • LessThanEqual:其中 x.field <= 参数
  • GreaterThan:其中 x.field >参数
  • GreaterThanEqual:其中 x.字段 >= 参数

对于JPA查询与比较,我们也可以使用关键字。DateAfterBefore

  • After:其中 x.dateField >参数
  • Before:其中 x.dateField <参数
List<Tutorial> findByLevelGreaterThan(int level);

List<Tutorial> findByCreatedAtGreaterThanEqual(Date date);

List<Tutorial> findByCreatedAtAfter(Date date);

List<Tutorial> findByLevelBetween(int start, int end);

List<Tutorial> findByLevelBetweenAndPublished(int start, int end, boolean isPublished);

List<Tutorial> findByCreatedAtBetween(Date start, Date end);

结果:

tutorials = tutorialRepository.findByLevelGreaterThan(3);
show(tutorials);
/*
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

Date myDate = new SimpleDateFormat("yyyy-MM-dd").parse("2022-05-11");

tutorials = tutorialRepository.findByCreatedAtGreaterThanEqual(myDate);
show(tutorials);
/*
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

tutorials = tutorialRepository.findByCreatedAtAfter(myDate);
show(tutorials);
/*
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

tutorials = tutorialRepository.findByLevelBetween(3, 5);
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

tutorials = tutorialRepository.findByLevelBetweenAndPublished(3, 5, true);
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
*/

Date myDate1 = new SimpleDateFormat("yyyy-MM-dd").parse("2022-04-11");
Date myDate2 = new SimpleDateFormat("yyyy-MM-dd").parse("2022-05-11");

tutorials = tutorialRepository.findByCreatedAtBetween(myDate1, myDate2);
show(tutorials);
/*
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
*/

带排序的 JPA 存储库查询

我们可以将关键字与(默认)一起使用,并使用派生查询按字段/列进行排序。OrderByAscDesc

List<Tutorial> findByOrderByLevel();
// same as
List<Tutorial> findByOrderByLevelAsc();

List<Tutorial> findByOrderByLevelDesc();

List<Tutorial> findByTitleContainingOrderByLevelDesc(String title);

List<Tutorial> findByPublishedOrderByCreatedAtDesc(boolean isPublished);

结果:

tutorials = tutorialRepository.findByOrderByLevel();
show(tutorials);
/*
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

tutorials = tutorialRepository.findByOrderByLevelDesc();
show(tutorials);
/*
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
*/

tutorials = tutorialRepository.findByTitleContainingOrderByLevelDesc("at");
show(tutorials);
/*
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
*/

tutorials = tutorialRepository.findByPublishedOrderByCreatedAtDesc(true);
show(tutorials);
/*
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
*/

如果要对多个字段进行排序,则需要在类的帮助下将对象作为参数传递。SortOrder

List<Tutorial> findByTitleContaining(String title, Sort sort);

List<Tutorial> findByPublished(boolean isPublished, Sort sort);

结果:

tutorials = tutorialRepository.findByTitleContaining("at", Sort.by("level").descending());
show(tutorials);
/*
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
*/

tutorials = tutorialRepository.findByPublished(false, Sort.by("level").descending());
show(tutorials);
/*
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
*/

List<Order> orders = new ArrayList<Order>();
orders.add(new Order(Sort.Direction.DESC, "level"));
orders.add(new Order(Sort.Direction.ASC, "title"));

tutorials = tutorialRepository.findByPublished(true, Sort.by(orders));
show(tutorials);
/*
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
*/

您可以在以下位置找到实现用于对多个字段/列进行排序的 Rest API 的方法:
Spring Data JPA 按多个列排序/排序|Spring Boot Rest API

带分页的 JPA 存储库查询

类似,您可以使用对象作为输入参数对派生查询进行分页。我们将此参数添加到方法定义中,作为返回类型。SortPageablePage<User>

Page<Tutorial> findAll(Pageable pageable);

Page<Tutorial> findByTitle(String title, Pageable pageable);

结果:

int page = 0;
int size = 3;

Pageable pageable = PageRequest.of(page, size);

tutorials = tutorialRepository.findAll(pageable).getContent();
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
*/

tutorials = tutorialRepository.findByTitleContaining("ring", pageable).getContent();
show(tutorials);
/*
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=2, title=Java Spring Boot, description=Spring Framework Description, level=1, published=false, createdAt=2022-03-11 00:00:00.0]
Tutorial [id=4, title=Spring Boot, description=Spring Boot Description, level=2, published=false, createdAt=2022-04-26 00:00:00.0]
*/

您可以在以下位置找到实现用于分页和过滤器的 Rest API 的方法:Spring Boot Rest API:
分页和过滤器示例|春季JPA,可分页

具有分页和排序功能的 JPA 存储库查询

Pageable也可用于分页和排序与方法的帮助。PageRequest.of()

Page<Tutorial> findAll(Pageable pageable);

Page<Tutorial> findByTitleContaining(String title, Pageable pageable);

结果:

int page = 0;
int size = 3;

Pageable pageable = PageRequest.of(page, size, Sort.by("level").descending());

tutorials = tutorialRepository.findAll(pageable).getContent();
show(tutorials);
/*
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
*/

pageable = PageRequest.of(page, size, Sort.by("level").descending());

tutorials = tutorialRepository.findByTitleContaining("at", pageable).getContent();
show(tutorials);
/*
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=3, title=Hibernate, description=Hibernate ORM Description, level=3, published=true, createdAt=2022-04-26 00:00:00.0]
Tutorial [id=1, title=Spring Data, description=Spring Data Description, level=3, published=true, createdAt=2022-03-11 00:00:00.0]
*/

您可以在以下位置找到实现用于分页和排序的 Rest API 的方法:Spring Boot Rest API:
分页和排序示例

JPA 删除多行

Spring Data JPA 还支持用于删除多行的派生查询:

@Transactional
void deleteAllByCreatedAtBefore(Date date);

结果:

Date outdate = new SimpleDateFormat("yyyy-MM-dd").parse("2022-05-1");

tutorialRepository.deleteAllByCreatedAtBefore(outdate);
tutorials = tutorialRepository.findAll();
show(tutorials);
/*
Tutorial [id=5, title=Spring JPA, description=Spring Data JPA Description, level=3, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=6, title=Spring Batch, description=Spring Batch Description, level=4, published=true, createdAt=2022-05-19 00:00:00.0]
Tutorial [id=7, title=Spring Security, description=Spring Security Description, level=5, published=false, createdAt=2022-05-19 00:00:00.0]
*/

运行 Spring JPA 派生查询项目

让我们打开,我们将在这里实现和自动连线接口来运行 JPA 查询方法。SpringJpaRepositoryQueryExampleApplication.javaCommandLineRunnerTutorialRepository

package com.bezkoder.spring.jpa.query;

// import ...

@SpringBootApplication
public class SpringJpaRepositoryQueryExampleApplication implements CommandLineRunner {

  @Autowired
  TutorialRepository tutorialRepository;

  public static void main(String[] args) {
    SpringApplication.run(SpringJpaRepositoryQueryExampleApplication.class, args);
  }

  @Override
  public void run(String... args) throws Exception {
    // call tutorialRepository methods here
  }

  private void show(List<Tutorial> tutorials) {
    tutorials.forEach(System.out::println);
  }
}

结论

今天,我们已经知道如何使用派生查询在 Spring 引导示例中使用 Spring JPA 存储库查询。

您可以使用以下方法继续编写 CRUD Rest API:
Spring Boot、Spring Data JPA – Rest CRUD API 示例

如果要为 JPA 存储库编写单元测试:
带有 @DataJpaTest 的 JPA 存储库的 Spring 引导单元测试

您还可以通过本教程了解:
– 如何在 AWS 上部署此 Spring 启动应用程序(免费)。
– dockerize withDocker Compose: Spring Boot and MySQL 示例
– 通过这篇文章
上传 Excel 文件并将数据存储在 MySQL 数据库中的方法– 通过这篇文章上传 CSV 文件并将数据存储在 MySQL 中。

祝你学习愉快!再见。

延伸阅读

  • 具有 Spring 安全性和 JWT 身份验证的安全 Spring 启动应用程序
  • 春季数据 JPA 参考文档
  • Spring 引导分页和排序示例

全栈 CRUD 应用程序:
–Vue + 弹簧引导示例–角度 8 + 弹簧引导示例–角度 10 + 弹簧引导示例–角度 11 + 弹簧引导示例–角度 12 + 弹簧引导示例–角度 13 + 弹簧引导示例–角度 14 + 弹簧引导示例
–反应 + 弹簧启动示例





 

源代码

您可以在Github 上找到本教程的完整源代码。

改用本机查询:Spring JPA 本机查询示例与
Spring 引导

或者JPQL:
Spring JPA@Query JPQL的例子

或 EntityManager:
Spring Boot 中的 JPA EntityManager 示例

关联:
–JPA 在春季引导中使用休眠的一对一示例–使用休眠和春季引导的 JPA 一对多示例–JPA 多对多示例与春季引导

中的休眠示例

您可以在以下教程中应用此实现:
–Spring JPA + H2 示例–Spring JPA + MySQL 示例–Spring JPA + PostgreSQL 示例–Spring JPA + Oracle 示例–Spring JPA + SQL Server 示例

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/40343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【教学类-19-02】20221127《ABCABC式-规律排序-A4竖版2份》(中班)

展示效果&#xff1a; 单人使用样式&#xff1a; 单页打印样式 ​ 背景需求&#xff1a; 中班幼儿需要掌握ABCABC的排序规律 ​ 前文制作了ABAB单元格色块&#xff0c;微调word表格的列数&#xff0c;调整python的参数&#xff0c;随机生成ABC排序样式&#xff0c;引导幼儿…

Android 单ABI架构适配指南:保姆级教学 INSTALL_FAILED_NO_MATCHING_ABIS

单ABI架构 64位 安装报错误详情如下 &#xff1a; Installation did not succeed. The application could not be installed: INSTALL_FAILED_NO_MATCHING_ABIS 产品需求&#xff1a; 单ABI架构支持拆解 迎合市场需求 32/64位独立包 目前项目ABI架构如下&#xff1a; …

基于Mxnet实现语义分割-整体多模型【完整、附部分源码】

文章目录前言语义分割发展史及意义一、数据集的准备二、基于Mxnet的语义分割框架构建1.引入库2.CPU/GPU配置3.数据标准化4.解析数据集到列表中JSON格式Label 图像的标注格式5.设置数据迭代器6.模型构建fcn模型结构pspnet模型结构deeplabv3模型结构deeplabv3模型结构ICNet模型结…

刷爆力扣之构建乘积数组

刷爆力扣之构建乘积数组 HELLO&#xff0c;各位看官大大好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 今天阿呆继续记录下力扣刷题过程&#xff0c;收录在专栏算法中 &#x1f61c;&#x1f61c;&#x1f61c; 该专栏按照不同类别标签进行刷题&#xff0c…

合作对策模型的简单实现

以如下题目作为示例&#xff1a; 一位歌手(S)&#xff0c;一位钢琴家 (P) 和一位鼓手(D) 组成一个小乐队在俱乐部同台演出能得到演出费1000元&#xff0c;若歌手和钢琴家一起演出能得800元。而只有钢琴家和鼓手一起演出能得到650元&#xff0c;钢琴独奏表演能得300元&#xff…

表单与列表在HTML与CSS中是这么玩的

文章目录表单应用场景实例讲解表单描述标签的使用 label表单约束属性详解表单访问限制技巧常用字段类型扩展隐藏与表单提交技巧表单验证使用总结大文本与列表框技巧详解选项框标准打开方式文件上传的正确打开方式时期与时间表单项使用详解搜索表单与DATALIST数据列表表单历史数…

【Java多线程】线程状态及线程方法大全

➤ Java多线程编程【一文全解】 文章目录线程状态线程方法> 停止线程 stop( )> 线程休眠 sleep( )> 线程礼让 yield( )> 线程强行执行 join( )> 线程状态观测 Thread.State> 线程的优先级 Priority> 守护多线程 daemon线程状态 线程有五大状态: 创建状态…

Java代码审计——XML 外部实体注入(XXE)

目录 前言&#xff1a; &#xff08;一&#xff09;XML 的常见接口 1&#xff0e;XMLReader 2&#xff0e;SAXBuilder 3&#xff0e;SAXReader 4&#xff0e;SAXParserFactory 5&#xff0e;Digester 6&#xff0e;DocumentBuilderFactory (二&#xff09;XXE 漏洞审计…

MongoDB的安装

配置环境变量,将F:\MongoDB\Server\bin的路径添加到PATH环境变量中配置环境变量,将F:\MongoDB\Server\bin的路径添加到PATH环境变量中 1、下载 在安装数据库之前将所有杀毒软件、防护软件全部关闭掉 官网下载地址&#xff1a;Download MongoDB Community Server | MongoDB …

【软件测试】测试人我明明测了,生产环境还出问题?又出幺蛾子......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试人对于线上问题…

大数据_数据中台建设与架构

目录 一、持续让数据用起来的机制框架 二、数据中台建设方法论 三、数据中台架构 一、持续让数据用起来的机制框架 数据中台的使命就是持续让数据用起来&#xff0c;它的根本性特点就是把“数据资产”作为基础要素独立出来&#xff0c;让成为资产的数据作为生产资料融入业务…

【SVM分类】基于matlab鸽群算法优化支持向量机SVM分类【含Matlab源码 2242期】

⛄一、鸽群算法简介 基于鸽群在归巢过程中的特殊导航行为,Duan等提出了一种仿生群体智能优化算法———鸽群优化算法.在这个算法中,通过模仿鸽子在寻找目标的不同阶段使用不同导航工具这一机制,提出了2种不同的算子模型: 1)地图和指南针算子(map and compass operator).鸽子可…

ElasticSearch入门

1. ELASTICSEARCH 1、安装elastic search dokcer中安装elastic search &#xff08;1&#xff09;下载ealastic search和kibana docker pull elasticsearch:7.6.2 docker pull kibana:7.6.2&#xff08;2&#xff09;配置 mkdir -p /mydata/elasticsearch/config mkdir -p…

day01 Redis

day01 Redis 第一章 非关系型数据库的简介 第一节 技术发展线路 第二节 互联网发展所面临的问题 1. Web1.0 时代 2. Web2.0时代 3. 互联网三高问题 3.1 高并发、大流量 大型网站系统需要面对高并发(QPS)用户&#xff0c;大流量访问。Google日均PV数35亿&#xff0c;日均IP…

centos8.4下搭建 rocketmq集群部署 4.9.4

1.简单介绍 搭建rocketmq集群,nameserver至少3个节点&#xff0c;brokerserver采用2主2从同步&#xff0c;服务器资源多的&#xff0c;可以至少部署在7台服务器上&#xff0c;资源少的可以准备至少3台服务器 172.16.4.15nameserver172.16.4.16nameserver172.16.4.17nameserver…

三维种子点生长算法(以及Python递归深度问题)

前言 种子点生长算法是从一个种子点向周围的遍历图像的每个像素的图遍历算法。 通常在二维中有8邻域方法&#xff0c;三维中有6邻域与26邻域方法。 本文实现了三维种子点生长的6邻域算法。 种子点生长算法本质上是对图像的连通部分进行遍历&#xff0c;因此可以分别利用深度优…

spring initializr脚手架搭建详解

前段时间&#xff0c;我在「基于start.spring.io&#xff0c;我实现了Java脚手架定制」一文中讲述了敝司的微服务脚手架落地过程中的前世今生&#xff0c;并提到了基于 spring initializr 的搭建了 2.0 版本的脚手架。今天我打算和你分享一下这其中的实现过程与细节&#xff0c…

Vue3 如何实现一个全局搜索框

前言&#xff1a;自从学习 vue 以来&#xff0c;就对 vue 官网全局的 command K 调出全局关键词搜索这个功能心心念念。恰好最近项目也是需要实现一个全局搜索的功能&#xff0c;也正好可以正大光明的带薪学习这个功能的思路。网上的教程水平参差不齐&#xff0c;而恰好之前的…

qmake 与 配置文件

用qmake生成makefile的时候&#xff0c;背后会先执行一堆用qmake language编写的库文件&#xff08;配置文件&#xff09;&#xff0c;用于初始化一些环境相关的工作&#xff0c;为后续解析pro文件做准备。 下面是qmake解析一个新建的qt工程的pro文件背后所解析的配置文件的文件…

2022-11-27阿里云物联网平台 MICROPYTHON记录

之前写过EMQX在阿里云的云服务器上搭建流程&#xff0c;近期云服务器到期了&#xff0c;而且由于没有业务支撑短期也不打算再开云服务器了&#xff0c;但是物联网还是要用的&#xff0c;于是开了这个阿里云物联网的记录。 这个是比较详细的已有的博客记录 这个博客居然还有配套…