SQL 数据库
Spring 框架为使用 SQL 数据库提供了广泛的支持,从使用 JdbcClient
或 JdbcTemplate
的直接 JDBC 访问到完成诸如 Hibernate 之类的“对象关系映射”技术。Spring Data 提供了更高级别的功能:直接从接口创建 Repository
实现,并使用约定从方法名称生成查询。
配置 DataSource
Java 的 DataSource
接口提供了一种使用数据库连接的标准方法。
传统上,DataSource
使用 a 和一些凭证来建立数据库连接。URL
有关更高级的示例,请参阅“操作指南”的配置自定义 DataSource 部分,通常可以完全控制 DataSource 的配置。 |
嵌入式数据库支持
使用内存中嵌入式数据库开发应用程序通常很方便。 显然,内存数据库不提供持久存储。 您需要在应用程序启动时填充数据库,并准备好在应用程序结束时丢弃数据。
“How-to Guides” 部分包括有关如何初始化数据库的部分。 |
Spring Boot 可以自动配置嵌入式 H2、HSQL 和 Derby 数据库。
您无需提供任何连接 URL。
您只需包含对要使用的嵌入式数据库的构建依赖项。
如果 Classpath 上有多个嵌入式数据库,请设置 configuration 属性以控制使用哪个数据库。
将该属性设置为禁用嵌入式数据库的自动配置。spring.datasource.embedded-database-connection
none
如果您在测试中使用此功能,您可能会注意到,无论您使用多少个应用程序上下文,整个测试套件都会重用同一个数据库。
如果要确保每个上下文都有一个单独的嵌入式数据库,则应设置为 。 |
例如,典型的 POM 依赖项如下所示:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
您需要对嵌入式数据库进行自动配置。
在此示例中,它是通过 传递方式拉入的。spring-jdbc spring-boot-starter-data-jpa |
如果出于某种原因,您确实为嵌入式数据库配置了连接 URL,请注意确保禁用数据库的自动关闭。
如果您使用 H2,则应使用 to 执行此操作。
如果您使用 HSQLDB,则应确保未使用 HSQLDB。
禁用数据库的自动关闭可以让 Spring Boot 控制数据库何时关闭,从而确保在不再需要访问数据库时进行关闭。DB_CLOSE_ON_EXIT=FALSE shutdown=true |
连接到生产数据库
生产环境数据库连接也可以使用池化DataSource
进行自动配置。
DataSource 配置
DataSource 配置由 中的外部配置属性控制。
例如,您可以在 :spring.datasource.*
application.properties
-
Properties
-
YAML
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring:
datasource:
url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
您至少应该通过设置属性来指定 URL。
否则, Spring Boot 会尝试自动配置嵌入式数据库。spring.datasource.url |
Spring Boot 可以从 URL 中推断出大多数数据库的 JDBC 驱动程序类。
如果需要指定特定类,可以使用该属性。spring.datasource.driver-class-name |
要创建池化 DataSource ,我们需要能够验证有效的 Driver 类是否可用,因此我们在执行任何操作之前都会检查一下。
换句话说,如果你设置了 ,那么该类必须是可加载的。spring.datasource.driver-class-name=com.mysql.jdbc.Driver |
有关更多支持的选项,请参阅 DataSourceProperties
API 文档。
这些是无论实际实现如何都有效的标准选项。
还可以使用各自的前缀 (、 、 和 )微调特定于实现的设置 。
有关更多详细信息,请参阅您正在使用的连接池实现的文档。spring.datasource.hikari.*
spring.datasource.tomcat.*
spring.datasource.dbcp2.*
spring.datasource.oracleucp.*
例如,如果您使用 Tomcat 连接池,则可以自定义许多其他设置,如以下示例所示:
-
Properties
-
YAML
spring.datasource.tomcat.max-wait=10000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.test-on-borrow=true
spring:
datasource:
tomcat:
max-wait: 10000
max-active: 50
test-on-borrow: true
这会将池设置为在没有可用连接的情况下等待 10000 毫秒,然后再引发异常,将最大连接数限制为 50 个,并在从池中借用连接之前验证连接。
支持的连接池
Spring Boot 使用以下算法来选择特定实现:
-
我们更喜欢 HikariCP 的性能和并发性。 如果 HikariCP 可用,我们总是会选择它。
-
否则,如果 Tomcat 池
DataSource
可用,我们就使用它。 -
否则,如果 Commons DBCP2 可用,我们就会使用它。
-
如果 HikariCP、Tomcat 和 DBCP2 都不可用,并且 Oracle UCP 可用,则使用它。
如果您使用 或 starters,则会自动获得对 HikariCP 的依赖。spring-boot-starter-jdbc spring-boot-starter-data-jpa |
您可以完全绕过该算法,并通过设置属性来指定要使用的连接池。
如果您在 Tomcat 容器中运行应用程序(默认情况下提供),这一点尤其重要。spring.datasource.type
tomcat-jdbc
其他连接池始终可以使用 DataSourceBuilder
手动配置。
如果您定义自己的DataSource
bean,则不会进行自动配置。
DataSourceBuilder
支持以下连接池:
-
光CP
-
Tomcat 池化
DataSource
-
共享 DBCP2
-
Oracle UCP 和
OracleDataSource
-
Spring 框架的
SimpleDriverDataSource
-
H2
Jdbc数据源
-
PostgreSQL
PGSimpleDataSource
-
C3P0
连接到 JNDI DataSource
如果将 Spring Boot 应用程序部署到 Application Server,则可能需要使用 Application Server 的内置功能来配置和管理 DataSource,并使用 JNDI 访问它。
该属性可以用作 , 和 属性的替代方法,以便从特定的 JNDI 位置访问 DataSource
。
例如,以下部分显示了如何访问 JBoss AS 定义的 DataSource
:spring.datasource.jndi-name
spring.datasource.url
spring.datasource.username
spring.datasource.password
application.properties
-
Properties
-
YAML
spring.datasource.jndi-name=java:jboss/datasources/customers
spring:
datasource:
jndi-name: "java:jboss/datasources/customers"
使用 JdbcTemplate
Spring 的JdbcTemplate
和NamedParameterJdbcTemplate
类是自动配置的,你可以将它们直接自动连接到你自己的 bean 中,如以下示例所示:
-
Java
-
Kotlin
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 ...
}
}
import org.springframework.jdbc.core.JdbcTemplate
import org.springframework.stereotype.Component
@Component
class MyBean(private val jdbcTemplate: JdbcTemplate) {
fun doSomething() {
jdbcTemplate.execute("delete from customer")
}
}
您可以使用属性自定义模板的某些属性,如以下示例所示:spring.jdbc.template.*
-
Properties
-
YAML
spring.jdbc.template.max-rows=500
spring:
jdbc:
template:
max-rows: 500
NamedParameterJdbcTemplate 在幕后重用了相同的JdbcTemplate 实例。
如果定义了多个JdbcTemplate 并且不存在主要候选者,则不会自动配置NamedParameterJdbcTemplate 。 |
使用 JdbcClient
Spring 的JdbcClient
是根据NamedParameterJdbcTemplate
的存在进行自动配置的。
您也可以将其直接注入到自己的 bean 中,如以下示例所示:
-
Java
-
Kotlin
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
private final JdbcClient jdbcClient;
public MyBean(JdbcClient jdbcClient) {
this.jdbcClient = jdbcClient;
}
public void doSomething() {
this.jdbcClient ...
}
}
import org.springframework.jdbc.core.simple.JdbcClient
import org.springframework.stereotype.Component
@Component
class MyBean(private val jdbcClient: JdbcClient) {
fun doSomething() {
jdbcClient.sql("delete from customer").update()
}
}
如果你依靠自动配置来创建底层的JdbcTemplate
,那么在客户端中也会考虑任何使用属性的自定义。spring.jdbc.template.*
JPA 和 Spring Data JPA
Java Persistence API 是一种标准技术,允许您将对象 “映射” 到关系数据库。
POM 提供了一种快速入门方法。
它提供以下关键依赖项:spring-boot-starter-data-jpa
-
Hibernate:最流行的 JPA 实现之一。
-
Spring Data JPA:帮助您实施基于 JPA 的存储库。
-
Spring ORM:来自 Spring 框架的核心 ORM 支持。
我们在这里不详细介绍 JPA 或 Spring Data。 您可以按照 spring.io 中的使用 JPA 访问数据指南进行操作,并阅读 Spring Data JPA 和 Hibernate 参考文档。 |
实体类
传统上,JPA “Entity” 类是在文件中指定的。
使用 Spring Boot 时,此文件不是必需的,而是使用 “Entity Scanning” 代替。
默认情况下,将扫描自动配置包。persistence.xml
考虑使用 @Entity
、@Embeddable
或 @MappedSuperclass
注释的任何类。
典型的实体类类似于以下示例:
-
Java
-
Kotlin
import java.io.Serializable;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.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
}
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.Id
import java.io.Serializable
@Entity
class City : Serializable {
@Id
@GeneratedValue
private val id: Long? = null
@Column(nullable = false)
var name: String? = null
private set
// ... etc
@Column(nullable = false)
var state: String? = null
private set
// ... additional members, often include @OneToMany mappings
protected constructor() {
// no-args constructor required by JPA spec
// this one is protected since it should not be used directly
}
constructor(name: String?, state: String?) {
this.name = name
this.state = state
}
}
您可以使用 @EntityScan 注释自定义实体扫描位置。
参见“操作指南”的 @Entity 定义与 Spring 配置分开 部分。 |
Spring Data JPA 存储库
Spring Data JPA 存储库是您可以定义用于访问数据的接口。
JPA 查询是根据您的方法名称自动创建的。
例如,接口可以声明一个方法来查找给定状态中的所有城市。CityRepository
findAllByState(String state)
对于更复杂的查询,您可以使用 Spring Data 的 Query
注释来注释您的方法。
Spring Data 存储库通常从 Repository
或 CrudRepository
接口扩展。
如果使用自动配置,则会在自动配置包中搜索存储库。
您可以自定义位置以使用 @EnableJpaRepositories 查找存储库。 |
以下示例显示了典型的 Spring Data 存储库接口定义:
-
Java
-
Kotlin
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<City, Long> {
Page<City> findAll(Pageable pageable);
City findByNameAndStateAllIgnoringCase(String name, String state);
}
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
interface CityRepository : Repository<City?, Long?> {
fun findAll(pageable: Pageable?): Page<City?>?
fun findByNameAndStateAllIgnoringCase(name: String?, state: String?): City?
}
Spring Data JPA 存储库支持三种不同的引导模式:default、deferred 和 lazy。
要启用延迟或延迟引导,请分别将属性设置为 或 。
当使用延迟或惰性引导时,自动配置的 EntityManagerFactoryBuilder
将使用上下文的 AsyncTaskExecutor
(如果有)作为引导执行程序。
如果存在多个,则将使用 named 的那个。spring.data.jpa.repositories.bootstrap-mode
deferred
lazy
applicationTaskExecutor
使用延迟或延迟引导时,请确保在应用程序上下文引导阶段之后推迟对 JPA 基础设施的任何访问。
您可以使用 |
我们只是触及了 Spring Data JPA 的皮毛。 有关完整详细信息,请参阅 Spring Data JPA 参考文档。 |
Spring Data Envers 存储库
如果 Spring Data Envers 可用,则 JPA 存储库将自动配置为支持典型的 Envers 查询。
要使用 Spring Data Envers,请确保您的存储库从 RevisionRepository
扩展,如以下示例所示:
-
Java
-
Kotlin
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<Country, Long, Integer>, Repository<Country, Long> {
Page<Country> findAll(Pageable pageable);
}
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
interface CountryRepository :
RevisionRepository<Country?, Long?, Int>,
Repository<Country?, Long?> {
fun findAll(pageable: Pageable?): Page<Country?>?
}
有关更多详细信息,请查看 Spring Data Envers 参考文档。 |
创建和删除 JPA 数据库
默认情况下,只有当您使用嵌入式数据库(H2、HSQL 或 Derby)时,才会自动创建 JPA 数据库。
您可以使用属性显式配置 JPA 设置。
例如,要创建和删除表,您可以将以下行添加到 :spring.jpa.*
application.properties
-
Properties
-
YAML
spring.jpa.hibernate.ddl-auto=create-drop
spring:
jpa:
hibernate.ddl-auto: "create-drop"
Hibernate 自己的内部属性名称(如果你记得更清楚的话)是 .
你可以通过使用来设置它,以及其他 Hibernate 原生属性(在将它们添加到实体管理器之前,前缀会被去除)。
以下行显示了为 Hibernate 设置 JPA 属性的示例:hibernate.hbm2ddl.auto spring.jpa.properties.* |
-
Properties
-
YAML
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
spring:
jpa:
properties:
hibernate:
"globally_quoted_identifiers": "true"
前面示例中的行将属性的值 of 传递给 Hibernate 实体管理器。true
hibernate.globally_quoted_identifiers
默认情况下,DDL 执行(或验证)被推迟到ApplicationContext
启动。
在 View 中打开 EntityManager
如果你正在运行一个 Web 应用程序, Spring Boot 默认注册OpenEntityManagerInViewInterceptor
以应用“在视图中打开EntityManager”模式,以允许在 Web 视图中进行延迟加载。
如果您不希望此行为,则应在 .spring.jpa.open-in-view
false
application.properties
Spring Data JDBC
Spring Data 包括对 JDBC 的存储库支持,并将为 CrudRepository
上的方法自动生成 SQL。
对于更高级的查询,提供了 @Query
注释。
当必要的依赖项位于 Classpath 上时, Spring Boot 将自动配置 Spring Data 的 JDBC 存储库。
它们可以通过对 的单个依赖项添加到您的项目中。
如有必要,你可以通过向应用程序添加 @EnableJdbcRepositories
注释或 AbstractJdbcConfiguration
子类来控制 Spring Data JDBC 的配置。spring-boot-starter-data-jdbc
有关 Spring Data JDBC 的完整详细信息,请参阅参考文档。 |
使用 H2 的 Web 控制台
-
您正在开发基于 servlet 的 Web 应用程序。
-
com.h2database:h2
位于 Classpath 上。 -
您正在使用 Spring Boot 的开发人员工具。
如果您不使用 Spring Boot 的开发人员工具,但仍希望使用 H2 的控制台,则可以配置值为 .spring.h2.console.enabled true |
H2 控制台仅用于开发期间,因此应注意确保未在生产环境中将其设置为。spring.h2.console.enabled true |
在安全应用程序中访问 H2 控制台
H2 控制台使用框架,因为它仅用于开发,所以不实施 CSRF 保护措施。 如果您的应用程序使用 Spring Security,则需要将其配置为
-
对针对控制台的请求禁用 CSRF 保护,
-
将 Header (标头) 设置为 On Responses (响应时)。
X-Frame-Options
SAMEORIGIN
有关 CSRF 和标头 X-Frame-Options 的更多信息,请参见 Spring Security Reference Guide。
在简单的设置中,可以使用如下所示的 SecurityFilterChain
:
-
Java
-
Kotlin
import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig;
import org.springframework.security.web.SecurityFilterChain;
@Profile("dev")
@Configuration(proxyBeanMethods = false)
public class DevProfileSecurityConfiguration {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
SecurityFilterChain h2ConsoleSecurityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher(PathRequest.toH2Console());
http.authorizeHttpRequests(yourCustomAuthorization());
http.csrf(CsrfConfigurer::disable);
http.headers((headers) -> headers.frameOptions(FrameOptionsConfig::sameOrigin));
return http.build();
}
}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Profile
import org.springframework.core.Ordered
import org.springframework.core.annotation.Order
import org.springframework.security.config.Customizer
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.web.SecurityFilterChain
@Profile("dev")
@Configuration(proxyBeanMethods = false)
class DevProfileSecurityConfiguration {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
fun h2ConsoleSecurityFilterChain(http: HttpSecurity): SecurityFilterChain {
return http.authorizeHttpRequests(yourCustomAuthorization())
.csrf { csrf -> csrf.disable() }
.headers { headers -> headers.frameOptions { frameOptions -> frameOptions.sameOrigin() } }
.build()
}
}
H2 控制台仅用于开发期间。 在生产环境中,关闭 CSRF 保护或允许 Web 站点框架可能会造成严重的安全风险。 |
PathRequest.toH2Console() 当控制台的路径已自定义时,也会返回正确的 Request Matcher。 |
使用 jOOQ
jOOQ 面向对象查询 (jOOQ) 是 Data Geekery 的一款热门产品,它从您的数据库生成 Java 代码,并允许您通过其 Fluent API 构建类型安全的 SQL 查询。 商业版和开源版都可以与 Spring Boot 一起使用。
代码生成
为了使用 jOOQ 类型安全的查询,您需要从数据库架构生成 Java 类。
您可以按照 jOOQ 用户手册中的说明进行操作。
如果您使用该插件,并且还使用了 “parent POM”,则可以安全地省略该插件的标签。
您还可以使用 Spring Boot 定义的版本变量(例如 )来声明插件的数据库依赖项。
下面的清单显示了一个示例:jooq-codegen-maven
spring-boot-starter-parent
<version>
h2.version
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<executions>
...
</executions>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
<configuration>
<jdbc>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:~/yourdatabase</url>
</jdbc>
<generator>
...
</generator>
</configuration>
</plugin>
使用 DSLContext
jOOQ 提供的 Fluent API 是通过 DSLContext
接口启动的。
Spring Boot 将 DSLContext
自动配置为 Spring Bean 并将其连接到您的应用程序DataSource
。
要使用 DSLContext
,您可以注入它,如以下示例所示:
-
Java
-
Kotlin
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;
}
}
import org.jooq.DSLContext
import org.springframework.stereotype.Component
import java.util.GregorianCalendar
@Component
class MyBean(private val create: DSLContext) {
}
jOOQ 手册倾向于使用一个名为 DSLContext 的变量。create |
然后,您可以使用 DSLContext
来构造查询,如以下示例所示:
-
Java
-
Kotlin
public List<GregorianCalendar> authorsBornAfter1980() {
return this.create.selectFrom(AUTHOR)
.where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
.fetch(AUTHOR.DATE_OF_BIRTH);
fun authorsBornAfter1980(): List<GregorianCalendar> {
return create.selectFrom<Tables.TAuthorRecord>(Tables.AUTHOR)
.where(Tables.AUTHOR?.DATE_OF_BIRTH?.greaterThan(GregorianCalendar(1980, 0, 1)))
.fetch(Tables.AUTHOR?.DATE_OF_BIRTH)
}
jOOQ SQL 方言
除非已配置该属性,否则 Spring Boot 会确定要用于数据源的 SQL 方言。
如果 Spring Boot 无法检测到方言,则使用 .spring.jooq.sql-dialect
DEFAULT
Spring Boot 只能自动配置 jOOQ 的开源版本支持的方言。 |
自定义 jOOQ
通过定义你自己的DefaultConfigurationCustomizer
Bean 来实现更高级的定制,该 bean 将在创建配置
@Bean
之前调用。
这优先于自动配置应用的任何内容。
如果您想完全控制 jOOQ 配置,您还可以创建自己的 Configuration
@Bean
。
使用 R2DBC
反应式关系数据库连接 (R2DBC) 项目为关系数据库带来了反应式编程 API。
R2DBC 的 Connection
提供了一种使用非阻塞数据库连接的标准方法。
连接是使用ConnectionFactory
提供的,类似于带有 jdbc 的DataSource
。
ConnectionFactory
配置由 中的外部配置属性控制。
例如,您可以在 :spring.r2dbc.*
application.properties
-
Properties
-
YAML
spring.r2dbc.url=r2dbc:postgresql://localhost/test
spring.r2dbc.username=dbuser
spring.r2dbc.password=dbpass
spring:
r2dbc:
url: "r2dbc:postgresql://localhost/test"
username: "dbuser"
password: "dbpass"
你不需要指定驱动程序类名,因为 Spring Boot 从 R2DBC 的 Connection Factory 发现中获取驱动程序。 |
至少应该提供 url。
URL 中指定的信息优先于单个属性,即 、 和 pooling 选项。name username password |
“How-to Guides” 部分包括有关如何初始化数据库的部分。 |
要自定义由 ConnectionFactory
创建的连接,即设置您不希望(或不能)在中央数据库配置中配置的特定参数,您可以使用 ConnectionFactoryOptionsBuilderCustomizer
@Bean
。
以下示例显示了如何手动覆盖数据库端口,而其余选项则从应用程序配置中获取:
-
Java
-
Kotlin
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);
}
}
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)
class MyR2dbcConfiguration {
@Bean
fun connectionFactoryPortCustomizer(): ConnectionFactoryOptionsBuilderCustomizer {
return ConnectionFactoryOptionsBuilderCustomizer { builder ->
builder.option(ConnectionFactoryOptions.PORT, 5432)
}
}
}
以下示例显示如何设置一些 PostgreSQL 连接选项:
-
Java
-
Kotlin
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<String, String> options = new HashMap<>();
options.put("lock_timeout", "30s");
options.put("statement_timeout", "60s");
return (builder) -> builder.option(PostgresqlConnectionFactoryProvider.OPTIONS, options);
}
}
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)
class MyPostgresR2dbcConfiguration {
@Bean
fun postgresCustomizer(): ConnectionFactoryOptionsBuilderCustomizer {
val options: MutableMap<String, String> = HashMap()
options["lock_timeout"] = "30s"
options["statement_timeout"] = "60s"
return ConnectionFactoryOptionsBuilderCustomizer { builder ->
builder.option(PostgresqlConnectionFactoryProvider.OPTIONS, options)
}
}
}
当 ConnectionFactory
Bean 可用时,常规的 JDBC DataSource
自动配置将退出。
如果您想保留 JDBC DataSource
自动配置,并且愿意承担在响应式应用程序中使用阻塞 JDBC API 的风险,请在应用程序中添加 @Configuration
类以重新启用它。@Import(DataSourceAutoConfiguration.class)
嵌入式数据库支持
与 JDBC 支持类似, Spring Boot 可以自动配置嵌入式数据库以进行反应式使用。 您无需提供任何连接 URL。 您只需包含要使用的嵌入式数据库的构建依赖项,如以下示例所示:
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
<scope>runtime</scope>
</dependency>
如果您在测试中使用此功能,您可能会注意到,无论您使用多少个应用程序上下文,整个测试套件都会重用同一个数据库。
如果要确保每个上下文都有一个单独的嵌入式数据库,则应设置为 。 |
使用 DatabaseClient
DatabaseClient
bean 是自动配置的,你可以将其直接自动连接到你自己的 bean 中,如以下示例所示:
-
Java
-
Kotlin
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<Map<String, Object>> someMethod() {
return this.databaseClient.sql("select * from user").fetch().all();
}
}
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.stereotype.Component
import reactor.core.publisher.Flux
@Component
class MyBean(private val databaseClient: DatabaseClient) {
// ...
fun someMethod(): Flux<Map<String, Any>> {
return databaseClient.sql("select * from user").fetch().all()
}
}
Spring Data R2DBC 存储库
Spring Data R2DBC 存储库是您可以定义以访问数据的接口。
查询是根据您的方法名称自动创建的。
例如,接口可以声明一个方法来查找给定状态中的所有城市。CityRepository
findAllByState(String state)
对于更复杂的查询,您可以使用 Spring Data 的 @Query
注释来注释您的方法。
Spring Data 存储库通常从 Repository
或 CrudRepository
接口扩展。
如果使用自动配置,则会在自动配置包中搜索存储库。
以下示例显示了典型的 Spring Data 存储库接口定义:
-
Java
-
Kotlin
import reactor.core.publisher.Mono;
import org.springframework.data.repository.Repository;
public interface CityRepository extends Repository<City, Long> {
Mono<City> findByNameAndStateAllIgnoringCase(String name, String state);
}
import org.springframework.data.repository.Repository
import reactor.core.publisher.Mono
interface CityRepository : Repository<City?, Long?> {
fun findByNameAndStateAllIgnoringCase(name: String?, state: String?): Mono<City?>?
}
我们只是触及了 Spring Data R2DBC 的皮毛。有关完整详细信息,请参阅 Spring Data R2DBC 参考文档。 |