JPA
本章介绍 JPA 仓库支持的特别之处。在继续了解 JPA 的具体内容之前,请确保您已透彻理解 使用 Spring Data 仓库 一节中讲解的基本概念。
Spring Data 仓库抽象的目标,是大幅减少为各种持久化存储实现数据访问层所需的样板代码。
本节小结
快速上手
通过 start.spring.io 创建一个基于 Spring 的项目,或在 Spring Tools 中创建一个 Spring 项目,是搭建可用环境的简便方式。
核心概念
Spring Data 仓库抽象中的核心接口是 Repository 。它以需要管理的领域类以及该领域类的标识符类型作为类型参数。该接口主要充当标记接口,用以捕获要处理的类型,并帮助您发现扩展了该接口的接口。
定义仓库接口
要定义仓库接口,您首先需要定义一个特定于领域类的仓库接口。该接口必须扩展 `Repository` ,并以领域类和 ID 类型作为类型参数。如果您希望为该领域类型暴露 CRUD 方法,可以扩展 `CrudRepository` 或其某个变体,而不是 `Repository` 。
配置
本节介绍通过以下任一方式配置 Spring Data JPA:
持久化实体
本节介绍如何使用 Spring Data JPA 持久化(保存)实体。
定义查询方法
仓库代理有两种方式从方法名派生特定存储的查询:
JPA 查询方法
本节介绍使用 Spring Data JPA 创建查询的各种方式。
值表达式基础
值表达式是 Spring 表达式语言( SpEL )与属性占位符解析的结合。它们将程序化表达式的强大求值能力,与借助属性占位符解析从 Environment (如配置属性)获取值的简洁性结合在一起。
投影
Spring Data 查询方法通常返回仓库所管理的一个或多个聚合根实例。然而,有时可能希望基于这些类型的某些属性创建投影。 Spring Data 允许建模专门的返回类型,以更有选择性地检索受管聚合的部分视图。
存储过程
JPA 2.1 规范引入了通过 StoredProcedureQuery API 调用存储过程的支持。我们引入了 @Procedure 注解,用于在仓库方法上声明存储过程元数据。
规约
JPA 的条件 API 让您能够以编程方式构建查询。 Spring Data JPA Specification 提供了一个小巧而专注的 API ,用于表达针对实体的谓词并在各仓库间复用。基于 Eric Evans 《领域驱动设计》一书中的规约概念,规约遵循相同的语义,提供使用 JPA 定义条件的 API 。要支持规约,您可以用 JpaSpecificationExecutor 接口扩展您的仓库接口,如下所示:
按示例查询
本章介绍按示例查询,并说明如何使用它。
向量搜索
随着生成式 AI 的兴起,向量数据库在数据库领域获得了强劲的发展势头。这些数据库能够高效地存储和查询高维向量,使其非常适合语义搜索、推荐系统和自然语言理解等任务。
事务性
默认情况下,从 CrudRepository 继承的方法会继承 SimpleJpaRepository 的事务配置。对于读操作,事务配置的 readOnly 标志设为 true 。其余方法均以普通的 @Transactional 配置,从而应用默认事务配置。由事务性仓库片段支撑的仓库方法,会从实际的片段方法继承事务属性。
锁定
要指定使用的锁模式,您可以在查询方法上使用 `@Lock` 注解,如下例所示:
审计
Spring Data 提供了完善的支持,可透明地跟踪谁创建或更改了实体以及更改发生的时间。要使用该功能,您必须为实体类配备审计元数据,这些元数据可通过注解或实现接口来定义。此外,必须通过注解配置或 XML 配置启用审计,以注册所需的基础设施组件。有关配置示例,请参阅特定存储部分。
合并持久化单元
Spring 支持使用多个持久化单元。但有时,您可能希望将应用程序模块化,同时又确保所有这些模块都运行在同一个持久化单元中。为启用这种行为, Spring Data JPA 提供了一个 PersistenceUnitManager 实现,它会根据持久化单元的名称自动合并持久化单元,如下例所示:
CDI 集成
仓库接口的实例通常由容器创建,在使用 Spring Data 时, Spring 是最自然的选择。 Spring 为创建 Bean 实例提供了完善的支持,如「创建仓库实例」一节所述。自 1.1.0 版起, Spring Data JPA 自带一个自定义 CDI 扩展,允许在 CDI 环境中使用仓库抽象。该扩展包含在 JAR 中。要启用它,只需将 Spring Data JPA 的 JAR 加入 classpath 。
自定义仓库实现
Spring Data 提供了多种选项,让您只需少量编码即可创建查询方法。但当这些选项无法满足您的需求时,您也可以为仓库方法提供自己的自定义实现。本节介绍如何做到这一点。
从聚合根发布事件
由仓库管理的实体就是聚合根。在领域驱动设计的应用中,这些聚合根通常会发布领域事件。 Spring Data 提供了一个名为 @DomainEvents 的注解,您可以将其用于聚合根的某个方法,以尽可能简便地完成该发布,如下例所示:
仓库方法的空值处理
返回单个聚合实例的仓库 CRUD 方法可以使用 Optional 来指示值可能不存在。除此之外, Spring Data 还支持在查询方法上返回以下包装器类型:
Spring Data 扩展
本节记录了一组 Spring Data 扩展,它们使 Spring Data 能够在多种场景下使用。目前,大多数集成都面向 Spring MVC 。
仓库查询关键词
下表列出 Spring Data 仓库查询派生机制普遍支持的、用于表达谓词的主题关键词。请查阅特定存储的文档以获取受支持关键词的确切列表,因为此处列出的某些关键词在特定存储中可能不受支持。
仓库查询返回类型
下表列出 Spring Data 仓库普遍支持的返回类型。请查阅特定存储的文档以获取受支持返回类型的确切列表,因为此处列出的某些类型在特定存储中可能不受支持。
提前优化
本章介绍 Spring Data 的提前( AOT )优化,这些优化建立在 Spring 的提前优化之上。
常见问题
例如,我想获得更详细的日志信息,以了解 `JpaRepository` 内部调用了哪些方法。如何获取这些信息?
术语表
面向切面编程