SQL Databases
{url-spring-framework-site}[Spring Framework] 提供了广泛的支持以支持使用 SQL 数据库,从直接使用 JDBC 访问 JdbcClient
或 JdbcTemplate
,到完整的 “object relational mapping” 技术,如 Hibernate,{url-spring-data-site}[Spring Data] 提供了其他层级功能:直接从界面创建 Repository
实现,并使用约定从方法名称生成查询。
Configure a DataSource
Java 的 javax.sql.DataSource
界面提供了一种与数据库连接一起工作的标准方法,传统上,DataSource
使用 URL
以及一些凭证来建立数据库连接。
有关更高级的示例,请参阅 the “How-to” section,通常用于完全控制 DataSource 的配置。 |
Embedded Database Support
通过使用内存中嵌入式数据库通常很方便。显然,内存中数据库不提供持久存储,你的应用程序启动时需要填充你的数据库,并且当你的应用程序结束时要准备好丢弃数据。
“How-to” 部分包含 section on how to initialize a database。 |
Spring Boot 可以自动配置嵌入式 H2、 HSQL 和 Derby 数据库,你不需要提供任何连接 URL,你只需要包含要使用的嵌入式数据库的构建依赖项,如果 classpath 上存在多个嵌入式数据库,设置 configprop: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>
您需要依赖 |
如果由于某种原因而配置了嵌入式数据库的连接 URL,请注意确保禁用数据库的自动关闭。如果您使用 H2,则应该使用 |
DataSource Configuration
DataSource 配置由 spring.datasource.*
中的外部配置属性控制。例如,您可以在 application.properties
中声明以下部分:
spring: datasource: url: "jdbc:mysql://localhost/test" username: "dbuser" password: "dbpass"
您应该至少通过设置 configprop:spring.datasource.url[] 属性指定 URL。否则,Spring Boot 将尝试自动配置一个嵌入式数据库。 |
Spring Boot 可以从 URL 推导出大多数数据库的 JDBC 驱动程序类。如果您需要指定特定的类,则可以使用 configprop:spring.datasource.driver-class-name[] 属性。 |
为了创建池化 |
请参阅 {code-spring-boot-autoconfigure-src}/jdbc/DataSourceProperties.java[DataSourceProperties
] 以获取更多受支持的选项。这些是与 the actual implementation 无关的标准选项。还可以通过使用它们各自的前缀 (spring.datasource.hikari.
, spring.datasource.tomcat.
, spring.datasource.dbcp2.
, and spring.datasource.oracleucp.
) 来微调特定于实现的设置。请参阅正在使用的连接池实现的文档以获取更多详细信息。
例如,如果您使用 {url-tomcat-docs}/jdbc-pool.html#Common_Attributes[Tomcat 连接池],则可以自定义许多其他设置,如下例所示:
spring: datasource: tomcat: max-wait: 10000 max-active: 50 test-on-borrow: true
这会将池设置在没有可用连接时在抛出异常前等待 10000ms,将最大连接数限制为 50,并在从池中借用连接之前验证连接。
Supported Connection Pools
Spring Boot 使用以下算法选择特定实现:
-
我们更喜欢 HikariCP ,因为它具有高性能和并发性。如果 HikariCP 可用,我们总会选择它。
-
否则,如果 Tomcat 池化
DataSource
可用,我们就会使用它。 -
否则,如果 Commons DBCP2 可用,我们就使用它。
-
如果 HikariCP、Tomcat 和 DBCP2 均不可用,并且 Oracle UCP 可用,我们就会使用它。
如果您使用的是 |
您可以通过设置 configprop:spring.datasource.type[] 属性来完全绕过该算法并指定要使用的连接池。如果您在 Tomcat 容器中运行应用程序,则这一点尤为重要,因为 tomcat-jdbc
是默认提供的。
使用 DataSourceBuilder
总是可以手动配置其他连接池。如果你定义了自有 DataSource
bean,不会自动配置。DataSourceBuilder
支持以下连接池:
-
HikariCP
-
Tomcat pooling
Datasource
-
Commons DBCP2
-
Oracle UCP &
OracleDataSource
-
Spring Framework’s
SimpleDriverDataSource
-
H2
JdbcDataSource
-
PostgreSQL
PGSimpleDataSource
-
C3P0
Connection to a JNDI DataSource
如果你将 Spring Boot 应用程序部署到应用程序服务器,你可以使用应用程序服务器的内置特性配置和管理 DataSource,并通过 JNDI 访问它。
configprop:spring.datasource.jndi-name[] 属性可以用作 configprop:spring.datasource.url[], configprop:spring.datasource.username[], 和 configprop:spring.datasource.password[] 属性的替代方法,以从特定 JNDI 位置访问 DataSource
。例如,application.properties
中的以下节显示了如何访问 JBoss AS 定义的 DataSource
:
spring: datasource: jndi-name: "java:jboss/datasources/customers"
Using JdbcTemplate
Spring 的 JdbcTemplate
和 NamedParameterJdbcTemplate
类是自动配置的,你可以 @Autowire
直接将其添加到自己的 bean,如以下示例所示:
你可以通过使用 spring.jdbc.template.*
属性来定制模板的一些属性,如以下示例所示:
spring: jdbc: template: max-rows: 500
|
Using JdbcClient
Spring 的 JdbcClient
是基于 NamedParameterJdbcTemplate
的存在自动配置的。你也可以直接将其注入到自己的 bean 中,如以下示例所示:
如果你依赖自动配置来创建基础 JdbcTemplate
,使用 spring.jdbc.template.*
属性的任何定制也能在客户端中得到考虑。
JPA and Spring Data JPA
Java Persistence API 是一项标准的技术,可以让你将 “map” 对象存储到关系数据库中。spring-boot-starter-data-jpa
POM 提供快速入门的方法。它提供以下关键依赖项:
-
Hibernate:最受欢迎的 JPA 实现之一。
-
Spring Data JPA:帮助你实现基于 JPA 的存储库。
-
Spring ORM:Spring Framework 的核心 ORM 支持。
我们在此不会深入讨论 JPA 或 {url-spring-data-site}[Spring Data]。你可以访问 [role="bare"][role="bare"]https://spring.io 的 “Accessing Data with JPA” 指南,并阅读 {url-spring-data-jpa-site}[Spring Data JPA] 和 Hibernate 参考文档。 |
Entity Classes
传统上,JPA “Entity” 类在 persistence.xml
文件中指定。使用 Spring Boot,无需此文件,而是改用 “Entity Scanning”。默认情况下,会扫描 auto-configuration packages。
考虑标注为 @Entity
、@Embeddable
或 @MappedSuperclass
的任何类。一个典型实体类类似于以下示例:
你可以通过使用 |
Spring Data JPA Repositories
{url-spring-data-jpa-site}[Spring Data JPA] 存储库是你用来访问数据的可以定义的界面。JPA 查询创建于你的方法名。例如,CityRepository
界面可声明一个 findAllByState(String state)
方法来查找给定状态的所有城市。
对于更复杂查询,你可以在你的方法中添加注释,添加 Spring Data 的 {url-spring-data-jpa-javadoc}/org/springframework/data/jpa/repository/Query.html[Query
] 注释。
Spring Data 存储库通常扩展自 {url-spring-data-commons-javadoc}/org/springframework/data/repository/Repository.html[Repository
] 或 {url-spring-data-commons-javadoc}/org/springframework/data/repository/CrudRepository.html[CrudRepository
] 接口。如果使用自动配置,那么将会检索 auto-configuration packages 存储库。
可以使用 |
以下示例显示了典型的 Spring Data 存储库接口定义:
Spring Data JPA 存储库支持三种不同的引导模式:默认、延迟和惰性。要启用延迟或惰性引导,将 configprop:spring.data.jpa.repositories.bootstrap-mode[] 属性分别设置为 deferred
或 lazy
。在使用延迟或惰性引导时,自动配置的 EntityManagerFactoryBuilder
将使用上下文的 AsyncTaskExecutor
,如果存在的话,作为引导执行程序。如果存在多个,那么将会使用名为 applicationTaskExecutor
的那个。
在使用延迟或惰性引导时,确保在应用程序上下文引导阶段后延迟对 JPA 基础设施的任何访问。您可以使用 |
我们几乎没有涉猎 Spring Data JPA。如果要获得详细信息,请参阅 {url-spring-data-jpa-docs}[Spring Data JPA 参考文档]。 |
Spring Data Envers Repositories
如果 {url-spring-data-envers-site}[Spring Data Envers] 可用,那么 JPA 存储库将被自动配置为支持典型的 Envers 查询。
要使用 Spring Data Envers,请确保您的存储库扩展自 RevisionRepository
,如以下示例中所示:
如果要获得更多详细信息,请查看 {url-spring-data-jpa-docs}/envers.html[Spring Data Envers 参考文档]。 |
Creating and Dropping JPA Databases
默认情况下,如果您使用嵌入式数据库(H2、HSQL 或 Derby),JPA 数据库将被自动创建 only。您可以使用 spring.jpa.*
属性来明确配置 JPA 设置。例如,要创建和删除表,您可以将以下行添加到您的 application.properties
:
spring: jpa: hibernate.ddl-auto: "create-drop"
如果是 Hibernate 自身的内部属性名称(如果您碰巧更好地记住了该名称),那么该名称将是 |
spring: jpa: properties: hibernate: "globally_quoted_identifiers": "true"
在前面的示例中,该行传递了 true
值给 Hibernate 实体管理器的 hibernate.globally_quoted_identifiers
属性。
默认情况下,DDL 执行(或验证)将延迟到 ApplicationContext
开始。还有一个 spring.jpa.generate-ddl
标记,但是如果 Hibernate 自动配置处于活动状态,将不使用它,因为 ddl-auto
设置更加详细。
Open EntityManager in View
如果您运行的是 Web 应用程序,那么 Spring Boot 默认注册 {url-spring-framework-javadoc}/org/springframework/orm/jpa/support/OpenEntityManagerInViewInterceptor.html[OpenEntityManagerInViewInterceptor
] 来应用 “Open EntityManager in View” 模式,以允许 Web 视图中的惰性加载。如果您不想要此行为,那么应该在您的 application.properties
中将 spring.jpa.open-in-view
设置为 false
。
Spring Data JDBC
Spring Data 包括对 JDBC 的存储库支持,并且将为 CrudRepository
上的方法自动生成 SQL。对于更高级的查询,提供了 @Query
注释。
当类路径上有必要的依赖项时,Spring Boot 将自动配置 Spring Data 的 JDBC 存储库。可以使用对 spring-boot-starter-data-jdbc
的单一依赖项将它们添加到您的项目。如有必要,您可以通过向您的应用程序添加 @EnableJdbcRepositories
注释或 AbstractJdbcConfiguration
子类来控制 Spring Data JDBC 的配置。
如果要获得 Spring Data JDBC 的详细信息,请参阅 {url-spring-data-jdbc-docs}[参考文档]。 |
Using H2’s Web Console
H2 database 提供了 browser-based console,Spring Boot 可以自动配置它。在满足以下条件时,控制台自动配置:
-
您正在开发基于 Servlet 的 Web 应用程序。
-
com.h2database:h2
在类路径中。
如果您不使用 Spring Boot 的开发者工具,但仍然希望使用 H2 的控制台,您可以使用 |
H2 控制台仅用于开发过程中,因此您应该注意确保 |
Changing the H2 Console’s Path
默认情况下,控制台可在 /h2-console
中使用。您可以通过使用 configprop:spring.h2.console.path[] 属性来自定义控制台的路径。
Accessing the H2 Console in a Secured Application
H2 控制台使用框架并且仅供开发使用,因此未实现 CSRF 保护措施。如果您的应用程序使用 Spring Security,则需要将其配置为
-
停用对控制台请求的 CSRF 保护,
-
将标头
X-Frame-Options
设置为SAMEORIGIN
在控制台的响应中。
可以在 Spring Security 参考指南中找到有关 {url-spring-security-docs}/features/exploits/csrf.html[CSRF] 和标头 {url-spring-security-docs}/features/exploits/headers.html#headers-frame-options[X-Frame-Options] 的更多信息。
在简单设置中,可以使用如下 SecurityFilterChain
:
H2 控制台仅用于开发过程中。在生产中,禁用 CSRF 保护或允许网站使用框架可能会产生严重的安全性风险。
|
Using jOOQ
面向对象的 jOOQ 查询 ( jOOQ) 是 Data Geekery 的一个流行产品,它根据您的数据库生成 Java 代码,并允许您通过它流畅的 API 构建类型安全的 SQL 查询。商业版和开源版都可与 Spring Boot 配合使用。
Code Generation
要使用 jOOQ 类型安全查询,您需要从数据库架构生成 Java 类。您可以按照 {url-jooq-docs}/#jooq-in-7-steps-step3[jOOQ 用户手册] 中的说明进行操作。如果您使用 jooq-codegen-maven
插件,并且还使用 spring-boot-starter-parent
“parent POM”,则可以安全地省略插件的 <version>
标记。您还可以使用 Spring Boot 定义的版本变量(例如 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>
Using DSLContext
jOOQ 提供的流畅 API 通过 org.jooq.DSLContext
启动界面。Spring Boot 将 DSLContext
自动配置为 Spring Bean,并将其连接到您的应用程序 DataSource
。要使用 DSLContext
,您可以注入它,如下例所示:
jOOQ 手册倾向于使用一个名为 |
然后,你可以使用 DSLContext
来构造你的查询,如下例所示:
Using R2DBC
响应式关系型数据库连接 ( R2DBC) 项目将响应式编程 API 引入到了关系型数据库中。R2DBC 的 io.r2dbc.spi.Connection
提供了一种使用非阻塞数据库连接的标准方法。使用 ConnectionFactory
提供连接,类似于使用 JDBC 中的 DataSource
。
ConnectionFactory
配置通过 spring.r2dbc.*
中的外部配置属性进行控制。例如,你可以在 application.properties
中声明以下部分:
spring: r2dbc: url: "r2dbc:postgresql://localhost/test" username: "dbuser" password: "dbpass"
你不必指定驱动程序类名,因为 Spring Boot 会从 R2DBC 的连接工厂发现中获取驱动程序。 |
至少应该提供 URL。URL 中指定的信息优先于单个属性,即 |
“How-to” 部分包括一个 section on how to initialize a database。 |
要自定义一个 ConnectionFactory
创建的连接,即设置在你的中心数据库配置中你不想 (或不能) 配置的特定参数,可以使用一个 ConnectionFactoryOptionsBuilderCustomizer
@Bean
。以下示例显示了如何在从应用程序配置中获取其余选项时手动覆盖数据库端口:
以下示例显示了如何设置某些 PostgreSQL 连接选项:
当一个 ConnectionFactory
bean 可用时,常规 JDBC DataSource
自动配置会停止。如果你想保留 JDBC DataSource
自动配置,并且愿意在响应式应用程序中使用阻塞 JDBC API 的风险,请在你的应用程序中一个 @Configuration
类中添加 @Import(DataSourceAutoConfiguration.class)
以重新启用它。
Embedded Database Support
与 the JDBC support 类似,Spring Boot 可以自动配置嵌入式数据库以供响应式使用。你不需要提供任何连接 URL。你只需要将构建依赖项包含到你想要使用的嵌入式数据库,如下例所示:
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
<scope>runtime</scope>
</dependency>
如果你在测试中使用这个功能,你可能会发现无论你使用多少个应用程序上下文,你的整个测试套件都会重复使用同一个数据库。如果你想确保每个上下文都有一个独立的嵌入式数据库,则应该将 |
Spring Data R2DBC Repositories
Spring Data R2DBC存储库是你用来访问数据的接口。查询会自动从你的方法名创建。例如,一个 `CityRepository`接口可能声明一个 `findAllByState(String state)`方法,用于查找给定状态中的所有城市。
对于更复杂的查询,你可以使用 Spring Data 的 {url-spring-data-r2dbc-javadoc}/org/springframework/data/r2dbc/repository/Query.html[Query
] 注释来注释你的方法。
Spring Data 存储库通常扩展自 {url-spring-data-commons-javadoc}/org/springframework/data/repository/Repository.html[Repository
] 或 {url-spring-data-commons-javadoc}/org/springframework/data/repository/CrudRepository.html[CrudRepository
] 接口。如果使用自动配置,那么将会检索 auto-configuration packages 存储库。
以下示例显示了典型的 Spring Data 存储库接口定义:
我们还只是粗略地介绍了 Spring Data R2DBC。有关完整信息,请参阅 {url-spring-data-r2dbc-docs}[Spring Data R2DBC 参考文档]。 |