**For identifiers to be generated, still use a final field in combination with an all-arguments persistence constructor (preferred) or a `with…` method*—
@@ -429,12 +429,12 @@ Spring 数据模块通常支持持有不同值的重写属性。从编程模型
Spring 数据存储库抽象的目标是显著减少为各种持久性存储实现数据访问层所需的样板代码的数量。
| |*Spring Data repository documentation and your module*<br/><br/>本章解释了 Spring 数据存储库的核心概念和接口。<br/>本章中的信息是从 Spring 数据共享模块中提取的。<br/>它使用了配置以及 Java 持久性 API( JPA)模块的代码示例。<br/>你应该调整 XML 名称空间声明和要扩展的类型,使其与你所使用的特定模块的等同物。“[名称空间引用](#repositories.namespace-reference)”涵盖了 XML 配置,该配置在支持存储库 API 的所有 Spring 数据模块中都受到支持。“[存储库查询关键字](#repository-query-keywords)”一般涵盖了存储库抽象支持的查询方法关键字。<br/>有关模块的具体功能的详细信息,请参见本文档中有关该模块的章节。|
| |*Spring Data repository documentation and your module*<br/><br/>本章解释了 Spring 数据存储库的核心概念和接口。<br/>本章中的信息是从 Spring 数据共享模块中提取的。<br/>它使用了配置以及 Java 持久性 API( JPA)模块的代码示例。<br/>你应该调整 XML 名称空间声明和要扩展的类型,使其与你所使用的特定模块的等同物。“[名称空间引用](#repositories.namespace-reference)”涵盖了 XML 配置,该配置在支持存储库 API 的所有 Spring 数据模块中都受到支持。“[存储库查询关键字](#repository-query-keywords)”一般涵盖了存储库抽象支持的查询方法关键字。<br/>有关模块特定功能的详细信息,请参见本文档有关该模块的章节。|
Spring 数据存储库抽象中的中心接口是`Repository`。它把要管理的域类以及域类的 ID 类型作为类型参数。这个接口主要充当一个标记接口,用于捕获要使用的类型,并帮助你发现扩展这个类型的接口。[“粗栓剂”](https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html)接口为正在管理的实体类提供了复杂的增删改查功能。
Spring 数据存储库抽象中的中心接口是`Repository`。它把要管理的域类以及域类的 ID 类型作为类型参数。这个接口主要充当一个标记接口,用于捕获要使用的类型,并帮助你发现扩展这个类型的接口。[`CrudRepository`](https://DOCS. Spring.io/ Spring-data/commons/DOCS/current/api/org/springframework/data/repository/crudrepository.html)接口为所管理的实体类提供了复杂的增删改查功能。
通常,存储库接口扩展`Repository`、`CrudRepository`或`PagingAndSortingRepository`。或者,如果不想扩展 Spring 数据接口,也可以使用`@RepositoryDefinition`对存储库接口进行注释。扩展`CrudRepository`公开了一组完整的方法来操作你的实体。如果你希望对要公开的方法有所选择,请将要公开的方法从`CrudRepository`复制到你的域存储库中。
通常,存储库接口扩展`Repository`、`CrudRepository`或`PagingAndSortingRepository`。或者,如果不想扩展 Spring 数据接口,也可以用`@RepositoryDefinition`注释存储库接口。扩展`CrudRepository`公开了一组完整的方法来操作你的实体。如果你希望对要公开的方法有所选择,那么可以将要公开的方法从`CrudRepository`复制到你的域存储库中。
在前面的示例中,你为所有域存储库定义了一个公共的基本接口,并公开了`findById(…)`以及`save(…)`,这些方法被路由到 Spring 数据提供的你选择的存储库的基本存储库实现(例如,如果你使用 JPA,实现是`SimpleJpaRepository`),因为它们匹配`CrudRepository`中的方法签名。因此`UserRepository`现在可以保存用户,通过 ID 查找单个用户,并触发查询以通过电子邮件地址查找`Users`。
在前面的示例中,你为所有域存储库定义了一个公共的基本接口,并公开了`findById(…)`以及`save(…)`,这些方法被路由到你选择的存储库的基础存储库实现中,该存储库由 Spring 数据提供(例如,如果你使用 JPA,实现是`SimpleJpaRepository`),因为它们匹配`CrudRepository`中的方法签名。因此`UserRepository`现在可以保存用户,通过 ID 查找单个用户,并触发查询以通过电子邮件地址查找`Users`。
| |中间存储库接口用`@NoRepositoryBean`注释。<br/>确保将该注释添加到所有存储库接口中,其中 Spring 数据不应在运行时为其创建实例。|
1. 如果存储库定义[扩展特定于模块的存储库](#repositories.multiple-modules.types),则它是特定 Spring 数据模块的有效候选者。
2. 如果域类是[使用特定于模块的类型注释](#repositories.multiple-modules.annotations),则它是特定 Spring 数据模块的有效候选者。 Spring 数据模块要么接受第三方注释(例如 JPA 的`@Entity`),要么提供自己的注释(例如`@Document`用于 Spring Data MongoDB 和 Spring Data ElasticSearch)。
2. 如果域类是[使用特定于模块的类型注释](#repositories.multiple-modules.annotations),则它是特定 Spring 数据模块的有效候选者。 Spring 数据模块要么接受第三方注释(例如 JPA 的`@Entity`),要么提供自己的注释(例如用于 Spring Data MongoDB 和 Spring Data ElasticSearch 的`@Document`)。
`PersonRepository`引用了`Person`,这是用 JPA `@Entity`注释的,所以这个存储库显然属于 Spring 数据 JPA。`UserRepository`引用`User`,这是用 Spring Data MongoDB 的`@Document`注释的。
`PersonRepository`引用`Person`,这是用 JPA `@Entity`注释的,所以这个存储库显然属于 Spring 数据 JPA。`UserRepository`引用了`User`,这是用 Spring Data MongoDB 的`@Document`注释的。
下面的糟糕示例展示了一个存储库,它使用带有混合注释的域类:
...
...
@@ -723,11 +723,11 @@ class Configuration { … }
以下策略可用于存储库基础结构来解析查询。使用 XML 配置,你可以通过`query-lookup-strategy`属性在名称空间配置策略。对于 Java 配置,可以使用`Enable${store}Repositories`注释的`queryLookupStrategy`属性。某些策略可能不支持特定的数据存储。
* 方法解析器支持为单个属性(例如,`findByLastnameIgnoreCase(…)`)或支持忽略 case 的类型的所有属性(通常是`String`实例——例如,`findByLastnameAndFirstnameAllIgnoreCase(…)`)设置`IgnoreCase`标志。是否支持忽略情况可能会因存储而异,因此请参阅引用文档中的相关部分以获取特定于存储的查询方法。
Spring 注释是用[JSR 305](https://jcp.org/en/jsr/detail?id=305)注释(一种休眠但广泛使用的 JSR)进行元注释的。JSR305 元注释允许工具供应商(例如[IDEA](https://www.jetbrains.com/help/idea/nullable-and-notnull-annotations.html)、[Eclipse](https://help.eclipse.org/oxygen/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm)和[Kotlin](https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types))以通用方式提供空安全支持,而无需对 Spring 注释进行硬编码支持。要为查询方法启用可否定性约束的运行时检查,你需要在包级别上通过在`package-info.java`中使用 Spring 的`@NonNullApi`来激活非可否定性,如以下示例所示:
...
...
@@ -983,7 +983,7 @@ Spring 注释是用[JSR 305](https://jcp.org/en/jsr/detail?id=305)注释(一
你还可以在 Spring 容器之外使用存储库基础设施——例如,在 CDI 环境中。在你的 Classpath 中仍然需要一些 Spring 库,但是,通常情况下,你也可以通过编程的方式设置存储库。 Spring 提供存储库支持的数据模块带有你可以使用的持久性技术特定的`RepositoryFactory`,如下所示:
你还可以在 Spring 容器之外使用存储库基础设施——例如,在 CDI 环境中。在你的 Classpath 中仍然需要一些 Spring 库,但是,通常情况下,你也可以通过编程的方式设置存储库。 Spring 提供存储库支持的数据模块附带你可以使用的持久性技术特有的`RepositoryFactory`,如下所示:
Spring 数据存储库是通过使用形成存储库组合的片段来实现的。片段是基本存储库、功能方面(如[QueryDsl](#core.extensions.querydsl))和自定义接口及其实现。每次向存储库接口添加一个接口时,都会通过添加一个片段来增强组合。基础存储库和存储库方面的实现由每个 Spring 数据模块提供。
Spring 数据存储库是通过使用形成存储库组合的片段来实现的。片段是基本存储库、功能方面(如[QueryDsl](#core.extensions.querydsl))和自定义接口及其实现。每次向存储库接口添加一个接口时,都会通过添加一个片段来增强组合。基础存储库和存储库方面的实现是由每个 Spring 数据模块提供的。
Spring 支持存储库的数据模块编程模型提供了各种 Web 支持。与 Web 相关的组件要求 Spring MVC 容器在 Classpath 上。其中一些甚至提供了[Spring HATEOAS](https://github.com/spring-projects/spring-hateoas)的集成。通常,通过在 JavaConfig 配置类中使用`@EnableSpringDataWebSupport`注释来启用集成支持,如下例所示:
Spring 支持存储库的数据模块编程模型提供了各种 Web 支持。与 Web 相关的组件需要 Spring MVC JAR 在 Classpath 上。其中一些甚至提供了[Spring HATEOAS](https://github.com/spring-projects/spring-hateoas)的集成。通常,通过在 JavaConfig 配置类中使用`@EnableSpringDataWebSupport`注释来启用集成支持,如下例所示:
例 47。启用 Spring 数据 Web 支持
...
...
@@ -1495,13 +1495,13 @@ class WebConfiguration {}
[上一节](#core.web)中显示的配置记录了一些基本组件:
* a[使用`DomainClassConverter`类](#core.web.basic.domain-class-converter),用于让 Spring MVC 从请求参数或路径变量解析存储库管理的域类的实例。
*[使用`DomainClassConverter`类](#core.web.basic.domain-class-converter)让 Spring MVC 从请求参数或路径变量解析存储库管理的域类实例。
* [HandlerMethodarGumentResolver’](#core.web.basic.paging-and-sorting)实现让 Spring MVC 从请求参数解析`Pageable`和`Sort`实例。
* [`HandlerMethodArgumentResolver`](#core.web.basic.paging-and-sorting)实现让 Spring MVC 从请求参数解析`Pageable`和`Sort`实例。
* [Jackson Modules](#core.web.basic.jackson-mappers)根据所使用的 Spring 数据模块,对`Point`和`Distance`之类的类型进行反/序列化,或者存储特定的类型。
*[Jackson 模块](#core.web.basic.jackson-mappers)以反-/序列化`Point`和`Distance`之类的类型,或者存储特定的类型,这取决于所使用的 Spring 数据模块。
###### Using the `DomainClassConverter` Class
###### 使用`DomainClassConverter`类
`DomainClassConverter`类允许你在 Spring MVC 控制器方法签名中直接使用域类型,这样你就不需要通过存储库手动查找实例,如下例所示:
|`sort`|Properties that should be sorted by in the format `property,property(,ASC|(desc)(,ignorecase)。默认的排序方向是区分大小写的升序。如果要切换方向或大小写敏感度,请使用多个`sort`参数——例如,`?sort=firstname&sort=lastname,asc&sort=city,ignorecase`。|
|`sort`|Properties that should be sorted by in the format `property,property(,ASC|desc)`. The default sort direction is case-sensitive ascending. Use multiple `sort` parameters if you want to switch direction or case sensitivity — for example, `?sort=firstname&sort=lastname,ASC&sort=city,ignorecase`。|
Spring Hateoas 附带一个表示模型类,该表示模型类允许使用必要的`Page`元数据以及链接来丰富`Page`实例的内容,从而使客户端能够轻松地在页面中导航。将`Page`转换为`PagedResources`是通过 Spring Hateoas`ResourceAssembler`接口的实现完成的,该接口称为`PagedResourcesAssembler`。下面的示例展示了如何使用`PagedResourcesAssembler`作为控制器方法参数:
Spring Hateoas 附带一个表示模型类(`PagedResources`),该表示模型类允许使用必要的`Page`元数据以及链接来丰富`Page`实例的内容,从而使客户端能够轻松地在页面中导航。将`Page`转换为`PagedResources`是通过 Spring Hateoas`ResourceAssembler`接口的实现完成的,该接口称为`PagedResourcesAssembler`。下面的示例展示了如何使用`PagedResourcesAssembler`作为控制器方法参数:
核心模块和一些存储特定的模块附带一组用于类型的 Jackson 模块,例如`org.springframework.data.geo.Distance`和`org.springframework.data.geo.Point`,由 Spring 数据域使用。一旦启用[web support](#core.web)并且`com.fasterxml.jackson.databind.ObjectMapper`可用,就会导入这些模块。
核心模块和一些特定的存储模块附带一组用于类型的 Jackson 模块,如`org.springframework.data.geo.Distance`和`org.springframework.data.geo.Point`,由 Spring 数据域使用。一旦启用[网络支持](#core.web)并且`com.fasterxml.jackson.databind.ObjectMapper`可用,就会导入这些模块。
可以使用 Spring 数据投影(在[预测](#projections)中描述)通过使用[JSONPath](https://goessner.net/articles/JsonPath/)表达式(需要[Jayway JsonPath](https://github.com/json-path/JsonPath)或[XPath](https://www.w3.org/TR/xpath-31/)表达式(需要[XmlBeam](https://xmlbeam.org/))来绑定传入的请求有效负载,如下例所示:
可以使用 Spring 数据投影(在[预测](#projections)中描述)通过使用[JSONPath](https://goessner.net/articles/JsonPath/)表达式(需要[Jayway Jsonpath](https://github.com/json-path/JsonPath)或[XPath](https://www.w3.org/TR/xpath-31/)表达式(需要[XmlBeam](https://xmlbeam.org/))来绑定传入的请求有效负载,如下例所示:
例 52。使用 JSONPath 或 XPath 表达式的 HTTP 有效负载绑定
...
...
@@ -1672,15 +1672,15 @@ public interface UserPayload {
你可以使用前面示例中所示的类型作为 Spring MVC 处理程序方法参数,或者在`RestTemplate`的方法之一上使用`ParameterizedTypeReference`。前面的方法声明将尝试在给定的文档中的任何地方找到`firstname`。`lastname`XML 查找是在传入文档的顶层执行的。它的 JSON 变体首先尝试一个顶级的`lastname`,但如果前者不返回一个值,则还会尝试在`lastname`子文档中嵌套的`user`。这样,在不需要客户端调用公开的方法(通常是基于类的有效负载绑定的一个缺点)的情况下,可以轻松地减轻源文档结构中的更改。
对于 Spring MVC,一旦处于活动状态并且所需的依赖关系在 Classpath 上可用,所需的转换器就被自动注册。要使用`RestTemplate`,请手动注册`ProjectingJackson2HttpMessageConverter`或`XmlBeamHttpMessageConverter`。
对于 Spring MVC,一旦处于活动状态并且所需的依赖关系在 Classpath 上可用,则所需的转换器被自动注册。要使用`RestTemplate`,请手动注册一个`ProjectingJackson2HttpMessageConverter`或`XmlBeamHttpMessageConverter`。
有关更多信息,请参见规范[Spring Data Examples repository](https://github.com/spring-projects/spring-data-examples)中的[Web 投影示例](https://github.com/spring-projects/spring-data-examples/tree/master/web/projection)。
Spring 数据提供了复杂的支持,以透明地跟踪谁创建或更改了一个实体以及何时发生了更改。为了从该功能中受益,你必须为你的实体类配备审计元数据,这些元数据可以使用注释或通过实现接口来定义。此外,必须通过注释配置或 XML 配置来启用审计,以注册所需的基础设施组件。有关配置示例,请参阅特定于商店的部分。
下面的示例展示了使用 Spring Security 的`Authentication`对象的接口的实现:
...
...
@@ -2302,7 +2302,7 @@ class SpringSecurityAuditorAware implements AuditorAware<User> {
}
```
该实现访问由 Spring Security 提供的`Authentication`对象,并查找你在`UserDetailsService`实现中创建的自定义`UserDetails`实例。这里我们假设你通过`UserDetails`实现公开了域用户,但是,基于找到的`Authentication`,你也可以从任何地方查找它。
该实现访问由 Spring Security 提供的`Authentication`对象,并查找你在`UserDetailsService`实现中创建的自定义`UserDetails`实例。在这里,我们假设你通过`UserDetails`实现公开了域用户,但是,基于找到的`Authentication`,你也可以从任何地方查找它。
#### 7.1.4.`ReactiveAuditorAware`
...
...
@@ -2366,9 +2366,9 @@ class SpringSecurityAuditorAware implements ReactiveAuditorAware<User> {
|Types that implement `Streamable` and take a `Streamable` constructor or factory method argument|公开构造函数或`….of(…)`/`….valueof(…)` 工厂方法的类型,以`Streamable`为参数。详见[返回自定义的可刷新包装器类型](#repositories.collections-and-iterables.streamable-wrapper)。|
|Types that implement `Streamable` and take a `Streamable` constructor or factory method argument|公开构造函数或`….of(…)`/`….valueOf(…)`工厂方法的类型,以`Streamable`为参数。详见[返回自定义的可刷新包装器类型](#repositories.collections-and-iterables.streamable-wrapper)。|