# 数据
Spring Boot 集成了许多数据技术,包括 SQL 和 NoSQL。
# 1. SQL 数据库
----------
[Spring Framework](https://spring.io/projects/spring-framework)为使用 SQL 数据库提供了广泛的支持,从使用`JdbcTemplate`直接访问 JDBC 到完成诸如 Hibernate 之类的“对象关系映射”技术。[Spring Data](https://spring.io/projects/spring-data)提供了一个额外的功能级别:直接从接口创建`Repository`实现,并使用约定从你的方法名称生成查询。
### 1.1.配置数据源
Java 的`javax.sql.DataSource`接口提供了一种处理数据库连接的标准方法。传统上,“数据源”使用`URL`以及一些凭据来建立数据库连接。
| |有关更高级的示例,请参见[“操作指南”部分](howto.html#howto.data-access.configure-custom-datasource),通常用于完全控制数据源的配置。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.1.1.嵌入式数据库支持
使用嵌入式数据库开发应用程序通常是很方便的。显然,内存数据库不提供持久存储。你需要在应用程序启动时填充数据库,并准备在应用程序结束时丢弃数据。
| |“how-to”部分包括[关于如何初始化数据库的一节](howto.html#howto.data-initialization)。|
|---|----------------------------------------------------------------------------------------------------------------|
Spring 引导可以自动配置嵌入式[H2](https://www.h2database.com)、[HSQL](http://hsqldb.org/)和[Derby](https://db.apache.org/derby/)数据库。你不需要提供任何连接 URL。你只需要对要使用的嵌入式数据库包含一个构建依赖项。如果在 Classpath 上有多个嵌入式数据库,请设置`spring.datasource.embedded-database-connection`配置属性以控制使用哪个数据库。将属性设置为`none`将禁用嵌入式数据库的自动配置。
| |如果你在测试中使用此功能,你可能会注意到,无论你使用的应用程序上下文的数量如何,整个测试套件都可以重用相同的数据库,如果你想确保每个上下文都有一个单独的嵌入式数据库,
,你应该将`spring.datasource.generate-unique-name`设置为`true`。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
例如,典型的 POM 依赖关系如下:
```
org.springframework.boot
spring-boot-starter-data-jpa
org.hsqldb
hsqldb
runtime
```
| |你需要对`spring-jdbc`有一个依赖关系,才能自动配置嵌入式数据库。
在本例中,它是通过`spring-boot-starter-data-jpa`传递地拉入的。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |无论出于何种原因,如果你确实为嵌入式数据库配置了连接 URL,请注意确保禁用数据库的自动关闭。
如果你使用 H2,则应使用`DB_CLOSE_ON_EXIT=FALSE`,如果你使用 HSQLDB,请使用
,你应该确保不使用`shutdown=true`。
禁用数据库的自动关机可以在数据库关闭时进行引导控制,从而确保在不再需要访问数据库时发生这种情况。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.1.2.与生产数据库的连接
还可以通过使用池`DataSource`自动配置生产数据库连接。
#### 1.1.3.数据源配置
数据源配置由`spring.datasource.*`中的外部配置属性控制。例如,你可以在`application.properties`中声明以下部分:
属性
```
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
```
Yaml
```
spring:
datasource:
url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
```
| |你至少应该通过设置`spring.datasource.url`属性来指定 URL。
否则, Spring 引导将尝试自动配置嵌入式数据库。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |Spring 引导可以从 URL 推断出大多数数据库的 JDBC 驱动程序类。
如果需要指定特定的类,可以使用`spring.datasource.driver-class-name`属性。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |对于要创建的池`DataSource`,我们需要能够验证一个有效的`Driver`类是可用的,所以我们在做任何事情之前都要检查它。
换句话说,如果你设置`spring.datasource.driver-class-name=com.mysql.jdbc.Driver`,那么这个类必须是可加载的。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
参见[`DataSource属性`](https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-autofigure/SRC/main/java/org/springframework/boot/autofigure/jdbc/dasourceproperties.java)以获得更多支持的选项。无论[实际执行情况](features.html#data.sql.datasource.connection-pool)如何,这些都是标准选项。也可以通过使用它们各自的前缀(`spring.datasource.hikari.*`,`spring.datasource.tomcat.*`,`spring.datasource.dbcp2.*`,和`spring.datasource.oracleucp.*`)来微调实现特定的设置。有关更多详细信息,请参见你正在使用的连接池实现的文档。
例如,如果使用[Tomcat connection pool](https://tomcat.apache.org/tomcat-9.0-doc/jdbc-pool.html#Common_Attributes),则可以自定义许多其他设置,如下例所示:
属性
```
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.test-on-borrow=true
```
Yaml
```
spring:
datasource:
tomcat:
max-wait: 10000
max-active: 50
test-on-borrow: true
```
这将设置池等待 10000ms,然后在没有可用连接的情况下抛出异常,将最大连接数量限制为 50,并在从池中借用连接之前验证连接。
#### 1.1.4.支持的连接池
Spring 启动使用以下算法来选择具体的实现方式:
1. 我们更喜欢[Hikaricp](https://github.com/brettwooldridge/HikariCP)的性能和并发性。如果有 Hikaricp,我们总是选择它。
2. 否则,如果 Tomcat 池`DataSource`可用,则使用它。
3. 否则,如果[Commons DBCP2](https://commons.apache.org/proper/commons-dbcp/)是可用的,我们就使用它。
4. 如果 HIKARICP、 Tomcat 和 DBCP2 都不可用,并且如果 Oracle UCP 可用,我们就使用它。
| |如果使用`spring-boot-starter-jdbc`或`spring-boot-starter-data-jpa`“starters”,则会自动获得对`HikariCP`的依赖关系。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------|
你可以完全绕过该算法,并通过设置`spring.datasource.type`属性来指定要使用的连接池。如果你在 Tomcat 容器中运行应用程序,这一点尤其重要,因为`tomcat-jdbc`是默认提供的。
总是可以使用`DataSourceBuilder`手动配置其他连接池。如果你定义了自己的`DataSource` Bean,则不会发生自动配置。`DataSourceBuilder`支持以下连接池:
* HikariCP
* Tomcat 池`Datasource`
* Commons DBCP2
* Oracle UCP&`OracleDataSource`
* Spring 框架的`SimpleDriverDataSource`
* h2`JdbcDataSource`
* PostgreSQL`PGSimpleDataSource`
#### 1.1.5.连接到 JNDI 数据源
如果你将 Spring 引导应用程序部署到应用程序服务器,那么你可能希望通过使用应用程序服务器的内置功能来配置和管理你的数据源,并通过使用 JNDI 访问它。
`spring.datasource.jndi-name`属性可以用作`spring.datasource.url`、`spring.datasource.username`和`spring.datasource.password`属性的替代选项,以从特定的 JNDI 位置访问`DataSource`。例如,`application.properties`中的以下部分显示了如何按照`DataSource`的定义访问 JBoss:
属性
```
spring.datasource.jndi-name=java:jboss/datasources/customers
```
Yaml
```
spring:
datasource:
jndi-name: "java:jboss/datasources/customers"
```
### 1.2.使用 JDBCTemplate
Spring 的`JdbcTemplate`和`NamedParameterJdbcTemplate`类是自动配置的,并且你可以将它们`@Autowire`直接放入你自己的 bean 中,如以下示例所示:
```
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final JdbcTemplate jdbcTemplate;
public MyBean(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void doSomething() {
this.jdbcTemplate ...
}
}
```
你可以使用`spring.jdbc.template.*`属性自定义模板的一些属性,如下例所示:
属性
```
spring.jdbc.template.max-rows=500
```
Yaml
```
spring:
jdbc:
template:
max-rows: 500
```
| |`NamedParameterJdbcTemplate`在幕后重用相同的`JdbcTemplate`实例。
如果定义了多个`JdbcTemplate`且不存在主要候选项,则`NamedParameterJdbcTemplate`不会自动配置。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
### 1.3. JPA 和 Spring 数据 JPA
Java Persistence API 是一种标准技术,它允许你将对象“映射”到关系数据库。`spring-boot-starter-data-jpa` POM 提供了一种快速入门的方法。它提供了以下关键依赖项:
* Hibernate:最流行的实现方式之一 JPA。
* Spring 数据 JPA:帮助你实现基于 JPA 的存储库。
* Spring ORM:来自 Spring 框架的核心 ORM 支持。
| |在这里,我们不会对 JPA 或[Spring Data](https://spring.io/projects/spring-data)进行过多的详细说明。
你可以按照[“Accessing Data with JPA”](https://spring.io/guides/gs/accessing-data-jpa/)中的[“Accessing Data with JPA”](https://spring.io/guides/gs/accessing-data-jpa/)指南,并阅读[Spring Data JPA](https://spring.io/projects/spring-data-jpa)和[Hibernate](https://hibernate.org/orm/documentation/)参考文档。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.3.1.实体类别
传统上, JPA“实体”类是在`persistence.xml`文件中指定的。在 Spring 启动时,这个文件不是必需的,而是使用“实体扫描”。默认情况下,将搜索主配置类下面的所有包(注释为`@EnableAutoConfiguration`或`@SpringBootApplication`的包)。
任何带有`@Entity`、`@Embeddable`或`@MappedSuperclass`注释的类都将被考虑。典型的实体类类似于以下示例:
```
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class City implements Serializable {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String state;
// ... additional members, often include @OneToMany mappings
protected City() {
// no-args constructor required by JPA spec
// this one is protected since it should not be used directly
}
public City(String name, String state) {
this.name = name;
this.state = state;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
// ... etc
}
```
| |你可以使用`@EntityScan`注释自定义实体扫描位置。
参见“[howto.html](howto.html#howto.data-access.separate-entity-definitions-from-spring-configuration)”操作方法。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.3.2. Spring 数据 JPA 存储库
[Spring Data JPA](https://spring.io/projects/spring-data-jpa)存储库是你可以定义以访问数据的接口。 JPA 查询是根据你的方法名称自动创建的。例如,一个`CityRepository`接口可以声明一个`findAllByState(String state)`方法来查找给定状态下的所有城市。
对于更复杂的查询,你可以使用 Spring data 的[`Query`](https://DOCS. Spring.io/ Spring-data/ JPA/DOCS/2.6.2/api/org/springframework/data/ JPA/repository/query.html)注释来注释你的方法。
Spring 数据存储库通常扩展自[`Repository`](https://DOCS. Spring.io/ Spring-data/commons/DOCS/2.6.2/api/org/springframework/data/repository/repository.html)或[`CrudRepository`(https://DOCS. Spring.io/ Spring-data/commons/DOCS/2.6.2/api/org/springframFramework/data/depository.html)接口。如果使用自动配置,那么存储库将从包含主配置类(用`@EnableAutoConfiguration`或`@SpringBootApplication`注释的类)的包中向下搜索。
下面的示例显示了典型的 Spring 数据存储库接口定义:
```
import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.City;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
public interface CityRepository extends Repository {
Page findAll(Pageable pageable);
City findByNameAndStateAllIgnoringCase(String name, String state);
}
```
Spring 数据 JPA 存储库支持三种不同的引导模式:默认模式、延迟模式和惰性模式。要启用延迟引导或延迟引导,将`spring.data.jpa.repositories.bootstrap-mode`属性分别设置为`deferred`或`lazy`。当使用延迟或延迟引导时,自动配置的`EntityManagerFactoryBuilder`将使用上下文的`AsyncTaskExecutor`(如果有的话)作为引导执行器。如果存在多个选项,将使用名为`applicationTaskExecutor`的选项。
| |当使用延迟引导或延迟引导时,请确保在应用程序上下文引导阶段之后推迟对 JPA 基础架构的任何访问。
你可以使用`SmartInitializingSingleton`来调用任何需要 JPA 基础架构的初始化。
对于创建为 Spring bean 的 JPA 组件(例如转换器),使用`ObjectProvider`来延迟依赖关系的解决(如果有的话)。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |我们几乎没有触及 Spring 数据 JPA 的表面。
有关完整的详细信息,请参见[Spring Data JPA reference documentation](https://docs.spring.io/spring-data/jpa/docs/2.6.2/reference/html)。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.3.3. Spring 数据影响存储库
如果[Spring Data Envers](https://spring.io/projects/spring-data-envers)可用, JPA 存储库将自动配置为支持典型的 Envers 查询。
要使用 Spring data envers,请确保你的存储库从`RevisionRepository`扩展,如下例所示:
```
import org.springframework.boot.docs.data.sql.jpaandspringdata.entityclasses.Country;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.history.RevisionRepository;
public interface CountryRepository extends RevisionRepository, Repository {
Page findAll(Pageable pageable);
}
```
| |有关更多详细信息,请查看[Spring Data Envers reference documentation](https://docs.spring.io/spring-data/envers/docs/2.6.2/reference/html/)。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.3.4.创建和删除 JPA 数据库
默认情况下,如果使用嵌入式数据库(H2、HSQL 或 Derby),将自动创建 JPA 数据库**只有**。你可以使用`spring.jpa.*`属性显式地配置 JPA 设置。例如,要创建和删除表格,你可以在`application.properties`中添加以下行:
属性
```
spring.jpa.hibernate.ddl-auto=create-drop
```
Yaml
```
spring:
jpa:
hibernate.ddl-auto: "create-drop"
```
| |Hibernate 自己的内部属性名称(如果你能更好地记住它的话)是`hibernate.hbm2ddl.auto`,
,你可以将其与其他 Hibernate 本机属性一起设置,通过使用`spring.jpa.properties.*`(前缀在将其添加到实体管理器之前被剥离)。
下面的一行显示了为 Hibernate 设置 JPA 属性的示例:|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
属性
```
spring.jpa.properties.hibernate[globally_quoted_identifiers]=true
```
Yaml
```
spring:
jpa:
properties:
hibernate:
"globally_quoted_identifiers": "true"
```
前面示例中的行将`hibernate.globally_quoted_identifiers`属性的值`true`传递给 Hibernate 实体管理器。
默认情况下,DDL 的执行(或验证)被推迟到`ApplicationContext`已经开始时。还有一个`spring.jpa.generate-ddl`标志,但如果 Hibernate 自动配置是活动的,则不会使用它,因为`ddl-auto`设置的粒度更细。
#### 1.3.5.在视图中打开 EntityManager
如果你正在运行一个 Web 应用程序, Spring 默认引导寄存器[`OpenEntityManagerInViewInterceptor`](https://DOCS. Spring.io/ Spring-framework/DOCS/5.3.16/javadoc-api/org/springframework/orm/ JPA/support/openentitymanagerinviewinterceptor.html)应用“Opentitymanager in view”模式,以允许在 Web 视图中进行延迟加载。如果不希望发生这种行为,则应在`application.properties`中将`spring.jpa.open-in-view`设置为`false`。
### 1.4. Spring 数据 JDBC
Spring 数据包括对 JDBC 的存储库支持,并且将为`CrudRepository`上的方法自动生成 SQL。对于更高级的查询,提供了`@Query`注释。
Spring 当必要的依赖关系在 Classpath 上时,启动将自动配置 Spring 数据的 JDBC 存储库。它们可以通过对`spring-boot-starter-data-jdbc`的单一依赖添加到你的项目中。如果有必要,你可以通过向应用程序添加`@EnableJdbcRepositories`注释或`JdbcConfiguration`子类来控制 Spring 数据 JDBC 的配置。
| |有关 Spring 数据 JDBC 的完整详细信息,请参见[参考文献](https://docs.spring.io/spring-data/jdbc/docs/2.3.2/reference/html/)。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------|
### 1.5.使用 H2 的网络控制台
[H2 数据库](https://www.h2database.com)提供了一个[基于浏览器的控制台](https://www.h2database.com/html/quickstart.html#h2_console), Spring 引导可以为你自动配置。当满足以下条件时,控制台将自动配置:
* 你正在开发一个基于 Servlet 的 Web 应用程序。
* `com.h2database:h2`在 Classpath 上。
* 你使用的是[Spring Boot’s developer tools](using.html#using.devtools)。
| |如果你不使用 Spring Boot 的开发工具,但仍想使用 H2 的控制台,则可以配置`spring.h2.console.enabled`属性,其值为`true`。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |H2 控制台仅用于开发过程中,因此你应该注意确保在生产过程中不将`spring.h2.console.enabled`设置为`true`。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.5.1.改变 H2 控制台的路径
默认情况下,控制台位于`/h2-console`。你可以使用`spring.h2.console.path`属性来定制控制台的路径。
### 1.6.使用 Jooq
Jooq 面向对象查询([jOOQ](https://www.jooq.org/))是[数据极客](https://www.datageekery.com/)中的一种流行产品,它从你的数据库生成 Java 代码,并允许你通过其 Fluent API 构建类型安全的 SQL 查询。商业版和开放源代码版都可以与 Spring boot 一起使用。
#### 1.6.1.代码生成
为了使用 Jooq 类型安全查询,你需要从数据库模式生成 Java 类。你可以按照[Jooq 用户手册](https://www.jooq.org/doc/3.14.15/manual-single-page/#jooq-in-7-steps-step3)中的说明进行操作。如果你使用`jooq-codegen-maven`插件,并且还使用`spring-boot-starter-parent`“parent POM”,则可以安全地省略该插件的``标记。你还可以使用 Spring 引导定义的版本变量(例如`h2.version`)来声明插件的数据库依赖关系。下面的清单展示了一个示例:
```
org.jooq
jooq-codegen-maven
...
com.h2database
h2
${h2.version}
org.h2.Driver
jdbc:h2:~/yourdatabase
...
```
#### 1.6.2.使用 DSLContext
由 Jooq 提供的 Fluent API 是通过`org.jooq.DSLContext`接口启动的。 Spring 引导自动将`DSLContext`配置为 Spring Bean,并将其连接到你的应用程序`DataSource`。要使用`DSLContext`,你可以注入它,如以下示例所示:
```
import java.util.GregorianCalendar;
import java.util.List;
import org.jooq.DSLContext;
import org.springframework.stereotype.Component;
import static org.springframework.boot.docs.data.sql.jooq.dslcontext.Tables.AUTHOR;
@Component
public class MyBean {
private final DSLContext create;
public MyBean(DSLContext dslContext) {
this.create = dslContext;
}
}
```
| |Jooq 手册倾向于使用一个名为`create`的变量来保存`DSLContext`。|
|---|--------------------------------------------------------------------------------|
然后,你可以使用`DSLContext`来构造查询,如下例所示:
```
public List authorsBornAfter1980() {
return this.create.selectFrom(AUTHOR)
.where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
.fetch(AUTHOR.DATE_OF_BIRTH);
```
#### 1.6.3.Jooq SQL 方言
除非已经配置了`spring.jooq.sql-dialect`属性,否则 Spring boot 将确定要用于数据源的 SQL 方言。如果 Spring boot 无法检测到该方言,则使用`DEFAULT`。
| |Spring 启动只能自动配置由开源版本的 Jooq 支持的方言。|
|---|------------------------------------------------------------------------------------------|
#### 1.6.4.定制 Jooq
可以通过定义你自己的`DefaultConfigurationCustomizer` Bean 来实现更高级的自定义,该自定义将在创建`org.jooq.Configuration``@Bean`之前调用。这优先于自动配置所应用的任何内容。
如果你想完全控制 Jooq 配置,还可以创建自己的`org.jooq.Configuration``@Bean`。
### 1.7.使用 R2DBC
反应式关系数据库连接([R2DBC](https://r2dbc.io))项目将反应式编程 API 引入到关系数据库中。R2DBC 的`io.r2dbc.spi.Connection`提供了一种处理非阻塞数据库连接的标准方法。使用`ConnectionFactory`提供连接,类似于使用 JDBC 提供`DataSource`。
`ConnectionFactory`配置由`spring.r2dbc.*`中的外部配置属性控制。例如,你可以在`application.properties`中声明以下部分:
属性
```
spring.r2dbc.url=r2dbc:postgresql://localhost/test
spring.r2dbc.username=dbuser
spring.r2dbc.password=dbpass
```
Yaml
```
spring:
r2dbc:
url: "r2dbc:postgresql://localhost/test"
username: "dbuser"
password: "dbpass"
```
| |你不需要指定驱动程序类名,因为 Spring Boot 从 R2DBC 的连接工厂发现获得驱动程序。|
|---|-------------------------------------------------------------------------------------------------------------------------------|
| |至少应该提供 URL。
URL 中指定的信息优先于单个属性,即`name`、`username`、`password`和池选项。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| |“how-to”部分包括[关于如何初始化数据库的一节](howto.html#howto.data-initialization.using-basic-sql-scripts)。|
|---|----------------------------------------------------------------------------------------------------------------------------------------|
要自定义由`ConnectionFactory`创建的连接,即设置在中央数据库配置中不希望(或不能)配置的特定参数,可以使用`ConnectionFactoryOptionsBuilderCustomizer``@Bean`。下面的示例展示了如何手动重写数据库端口,而其余的选项将从应用程序配置中获取:
```
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyR2dbcConfiguration {
@Bean
public ConnectionFactoryOptionsBuilderCustomizer connectionFactoryPortCustomizer() {
return (builder) -> builder.option(ConnectionFactoryOptions.PORT, 5432);
}
}
```
以下示例展示了如何设置一些 PostgreSQL 连接选项:
```
import java.util.HashMap;
import java.util.Map;
import io.r2dbc.postgresql.PostgresqlConnectionFactoryProvider;
import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryOptionsBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyPostgresR2dbcConfiguration {
@Bean
public ConnectionFactoryOptionsBuilderCustomizer postgresCustomizer() {
Map options = new HashMap<>();
options.put("lock_timeout", "30s");
options.put("statement_timeout", "60s");
return (builder) -> builder.option(PostgresqlConnectionFactoryProvider.OPTIONS, options);
}
}
```
当`ConnectionFactory` Bean 可用时,常规的 JDBC`DataSource`自动配置将退出。如果你希望保留 JDBC`DataSource`自动配置,并且对在反应性应用程序中使用阻塞 JDBC API 的风险感到满意,那么在应用程序中的`@Import(DataSourceAutoConfiguration.class)`类上添加`@Import(DataSourceAutoConfiguration.class)`以重新启用它。
#### 1.7.1.嵌入式数据库支持
与[JDBC 支持](features.html#data.sql.datasource.embedded)类似, Spring 引导可以自动配置嵌入式数据库以用于被动使用。你不需要提供任何连接 URL。你只需要对要使用的嵌入式数据库包含一个构建依赖项,如以下示例所示:
```
io.r2dbc
r2dbc-h2
runtime
```
| |如果在测试中使用此功能,你可能会注意到,无论你使用的应用程序上下文的数量如何,整个测试套件都可以重用相同的数据库,如果你想确保每个上下文都有一个单独的嵌入式数据库,
,你应该将`spring.r2dbc.generate-unique-name`设置为`true`。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
#### 1.7.2.使用 DatabaseClient
a`DatabaseClient` Bean 是自动配置的,你可以`@Autowire`它直接进入你自己的 bean 中,如以下示例所示:
```
import java.util.Map;
import reactor.core.publisher.Flux;
import org.springframework.r2dbc.core.DatabaseClient;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final DatabaseClient databaseClient;
public MyBean(DatabaseClient databaseClient) {
this.databaseClient = databaseClient;
}
// ...
public Flux