github编辑

9.1. SQL数据库

Spring框架arrow-up-right为使用 SQL 数据库提供了广泛的支持,从使用直接 JDBC 访问JdbcClientJdbcTemplate完成“对象关系映射”技术(例如 Hibernate)。 Spring Dataarrow-up-right提供了额外级别的功能:Repository直接从接口创建实现并使用约定从方法名称生成查询。

9.1.1. 配置数据源

Java 的javax.sql.DataSource接口提供了使用数据库连接的标准方法。传统上,DataSource使用 URL以及一些凭据来建立数据库连接。

请参阅“操作方法”部分arrow-up-right以获取更高级的示例,通常是为了完全控制数据源的配置。

嵌入式数据库支持

使用内存嵌入式数据库开发应用程序通常很方便。显然,内存数据库不提供持久存储。您需要在应用程序启动时填充数据库,并准备好在应用程序结束时丢弃数据。

“操作方法”部分包括有关如何初始化数据库的部分arrow-up-right

Spring Boot 可以自动配置嵌入式H2arrow-up-rightHSQLarrow-up-rightDerbyarrow-up-right数据库。您无需提供任何连接 URL。您只需包含对要使用的嵌入式数据库的构建依赖项。如果类路径上有多个嵌入式数据库,请设置spring.datasource.embedded-database-connection配置属性来控制使用哪一个。将属性设置为none禁用嵌入式数据库的自动配置。

如果您在测试中使用此功能,您可能会注意到,无论您使用的应用程序上下文数量如何,整个测试套件都会重复使用同一个数据库。如果您想确保每个上下文都有一个单独的嵌入式数据库,您应该设置spring.datasource.generate-unique-nametrue

例如,典型的 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,你应该设置DB_CLOSE_ON_EXIT=FALSE。如果您使用HSQLDB,您应该确保不使用shutdown=true。禁用数据库的自动关闭可以让 Spring Boot 控制数据库何时关闭,从而确保在不再需要访问数据库时关闭数据库。

连接到生产数据库

还可以使用池来自动配置生产数据库连接DataSource

数据源配置

数据源配置由spring.datasource.*. 例如,您可以在application.properties 中声明以下部分:

您至少应该通过设置spring.datasource.url属性来指定 URL。否则,Spring Boot 会尝试自动配置嵌入式数据库

Spring Boot 可以从 URL 推断出大多数数据库的 JDBC 驱动程序类。如果需要指定特定的类,可以使用该spring.datasource.driver-class-name属性。

为了创建池DataSource,我们需要能够验证有效的Driver类是否可用,因此我们在执行任何操作之前进行检查。换句话说,如果您设置了spring.datasource.driver-class-name=com.mysql.jdbc.Driver,那么该类必须是可加载的。

请参阅DataSourcePropertiesarrow-up-right参考资料 了解更多支持的选项。这些是无论实际实施arrow-up-right如何都有效的标准选项。还可以通过使用各自的前缀(spring.datasource.hikari.*spring.datasource.tomcat.*spring.datasource.dbcp2.*spring.datasource.oracleucp.*)来微调特定于实现的设置。有关更多详细信息,请参阅您正在使用的连接池实现的文档。

例如,如果您使用Tomcat 连接池arrow-up-right,则可以自定义许多其他设置,如以下示例所示:

如果没有可用连接,这会将池设置为在抛出异常之前等待 10000 毫秒,将最大连接数限制为 50,并在从池中借用连接之前验证连接。

支持的连接池

Spring Boot 使用以下算法来选择特定的实现:

  1. 我们更喜欢HikariCParrow-up-right的性能和并发性。如果 HikariCP 可用,我们总是选择它。

  2. 否则,如果 Tomcat 池DataSource可用,我们就使用它。

  3. 否则,如果Commons DBCP2arrow-up-right可用,我们将使用它。

  4. 如果 HikariCP、Tomcat 和 DBCP2 都不可用,而 Oracle UCP 可用,则我们使用它。

如果您使用spring-boot-starter-jdbcspring-boot-starter-data-jpa“starters”,您会自动获得对HikariCP.

您可以完全绕过该算法并通过设置spring.datasource.type属性来指定要使用的连接池。如果您在 Tomcat 容器中运行应用程序,这一点尤其重要,因为默认提供 tomcat-jdbc

始终可以使用DataSourceBuilder添加任何连接池. 如果您定义自己的DataSourcebean,则不会发生自动配置。DataSourceBuilder支持以下连接池:

  • HikariCP

  • Tomcat 池化Datasource

  • Commons DBCP2

  • Oracle UCP 和OracleDataSource

  • Spring框架的SimpleDriverDataSource

  • H2JdbcDataSource

  • PostgreSQLPGSimpleDataSource

  • C3P0

连接到 JNDI 数据源

如果将 Spring Boot 应用程序部署到应用程序服务器,您可能希望使用应用程序服务器的内置功能来配置和管理数据源,并使用 JNDI 访问它。

spring.datasource.jndi-name属性可用作spring.datasource.urlspring.datasource.usernamespring.datasource.password属性的替代,以从特定 JNDI 位置访问DataSource。例如,以下部分application.properties显示了如何访问 JBoss AS 定义的DataSource

9.1.2. 使用 JdbcTemplate

SpringJdbcTemplateNamedParameterJdbcTemplate类是自动配置的,您可以使用@Autowire将它们直接添加到您自己的 bean 中,如以下示例所示:

您可以通过属性来自定义模板的一些属性spring.jdbc.template.*,如下例所示:

NamedParameterJdbcTemplate 在幕后重用相同的JdbcTemplate 实例。如果定义了多个JdbcTemplate并且不存在主要候选者,则不会自动配置 NamedParameterJdbcTemplate

9.1.3. 使用 JdbcClient

SpringJdbcClient是根据NamedParameterJdbcTemplate自动配置的. 您也可以将其直接注入到您自己的 bean 中,如以下示例所示:

如果您依靠自动配置来创建底层 JdbcTemplate,则客户端也会考虑使用 spring.jdbc.template.*属性的任何自定义。

9.1.4. JPA 和 Spring Data JPA

Java Persistence API 是一种标准技术,可让您将对象“映射”到关系数据库。spring-boot-starter-data-jpaPOM提供了一种快速入门方法。它提供了以下关键依赖项:

  • Hibernate:最流行的 JPA 实现之一。

  • Spring Data JPA:帮助您实现基于 JPA 的存储库。

  • Spring ORM:Spring 框架的核心 ORM 支持。

我们在这里不过多讨论 JPA 或Spring Dataarrow-up-right的细节。您可以遵循spring.io中的arrow-up-right“使用 JPA 访问数据”arrow-up-right指南并阅读Spring Data JPAarrow-up-rightHibernatearrow-up-right参考文档。

实体类

传统上,JPA“实体”类是在persistence.xml文件中指定的。对于 Spring Boot,这个文件不是必需的,而是使用“Entity Scanning”。默认情况下会扫描自动配置包。arrow-up-right

任何用@Entity@Embeddable、 或@MappedSuperclass注解的类都会被考虑。典型的实体类类似于以下示例:

您可以使用@EntityScan注释自定义实体扫描位置。请参阅“从 Spring 配置中分离 @Entity 定义arrow-up-right”操作方法。

Spring Data JPA 存储库

Spring Data JPAarrow-up-right存储库是您可以定义来访问数据的接口。JPA 查询是根据您的方法名称自动创建的。例如,CityRepository接口可能声明一个findAllByState(String state)方法来查找给定州的所有城市。

对于更复杂的查询,您可以使用 Spring Data 的Queryarrow-up-right注释来注释您的方法。

Spring Data 存储库通常从Repositoryarrow-up-rightCrudRepositoryarrow-up-right接口扩展。如果您使用自动配置,则会在自动配置包中arrow-up-right搜索存储库。

您可以使用 @EnableJpaRepositories自定义位置来查找存储库。

以下示例显示了典型的 Spring Data 存储库接口定义:

Spring Data JPA 存储库支持三种不同的引导模式:默认、延迟和懒加载。要启用延迟或懒加载引导,请分别将该spring.data.jpa.repositories.bootstrap-mode属性设置为deferredlazy。当使用延迟或惰性引导时,自动配置EntityManagerFactoryBuilder将使用上下文AsyncTaskExecutor(如果有)作为引导执行器。如果存在多个,则将使用applicationTaskExecutor指定的那个。

使用延迟或惰性引导时,请确保在应用程序上下文引导阶段之后延迟对 JPA 基础结构的任何访问。您可以使用它SmartInitializingSingleton来调用任何需要 JPA 基础结构的初始化。对于作为 Spring bean 创建的 JPA 组件(例如转换器),请使用ObjectProvider延迟解析依赖项(如果有)。

我们仅仅触及了 Spring Data JPA 的皮毛。有关完整的详细信息,请参阅Spring Data JPA 参考文档arrow-up-right

Spring Data Envers 存储库

如果Spring Data Enversarrow-up-right可用,JPA 存储库会自动配置为支持典型的 Envers 查询。

要使用 Spring Data Envers,请确保您的存储库扩展RevisionRepository如同以下示例:

有关更多详细信息,请查看Spring Data Envers 参考文档arrow-up-right

创建和删除 JPA 数据库

默认情况下,仅当您使用嵌入式数据库(H2、HSQL 或 Derby)时才会自动创建 JPA 数据库。您可以使用spring.jpa.*属性显式配置 JPA 设置。例如,要创建和删除表,您可以将以下行添加到您的application.properties

Hibernate 自己的内部属性名称(如果您记得更好的话)是hibernate.hbm2ddl.auto。您可以通过使用spring.jpa.properties.*(在将它们添加到实体管理器之前删除前缀)来设置它以及其他 Hibernate 本机属性。以下行显示了为 Hibernate 设置 JPA 属性的示例:

前面示例中的行将hibernate.globally_quoted_identifiers属性的true值传递给Hibernate 实体管理器。

默认情况下,DDL 执行(或验证)被推迟到ApplicationContext开始为止。还有一个spring.jpa.generate-ddl标志,但如果 Hibernate 自动配置处于活动状态,则不会使用它,因为ddl-auto设置了更细粒度。

在视图中打开EntityManager

如果您正在运行 Web 应用程序,Spring Boot 默认情况下会注册OpenEntityManagerInViewInterceptorarrow-up-right以应用“在视图中打开 EntityManager”模式,以允许在 Web 视图中延迟加载。如果您不希望出现这种行为,您应该在您的application.propertiesspring.jpa.open-in-view设置为false.

9.1.5. Spring Data JDBC

Spring Data 包括对 JDBC 的存储库支持,并将自动为CrudRepository. 对于更高级的查询,提供了@Query注释。

当类路径上有必要的依赖项时,Spring Boot 将自动配置 Spring Data 的 JDBC 存储库。可以将它们添加到您的项目中,并仅依赖于spring-boot-starter-data-jdbc. 如有必要,您可以通过向应用程序添加@EnableJdbcRepositories注释或AbstractJdbcConfiguration子类来控制 Spring Data JDBC 的配置。

有关 Spring Data JDBC 的完整详细信息,请参阅参考文档arrow-up-right

9.1.6. 使用 H2 的 Web 控制台

H2 数据库arrow-up-right提供了一个基于浏览器的控制台arrow-up-right,Spring Boot 可以为您自动配置。当满足以下条件时,控制台会自动配置:

如果您不使用 Spring Boot 的开发人员工具,但仍想使用 H2 的控制台,则可以将spring.h2.console.enabled属性配置为true

H2 控制台仅供开发期间使用,因此您应注意确保在生产中spring.h2.console.enabled未将其设置为true

更改 H2 控制台的路径

默认情况下,控制台位于/h2-console。您可以使用spring.h2.console.path属性自定义控制台的路径。

在安全应用程序中访问 H2 控制台

H2 Console 使用框架,仅用于开发,没有实施 CSRF 保护措施。如果您的应用程序使用 Spring Security,则需要将其配置为

  • 对针对控制台的请求禁用 CSRF 保护,

  • 将标头设置X-Frame-OptionsSAMEORIGIN来自控制台的响应。

有关CSRFarrow-up-right和标头X-Frame-Options 的arrow-up-right更多信息可以在 Spring Security 参考指南中找到。

在简单的设置中,可以使用如下所示的SecurityFilterChain内容:

H2 控制台仅供开发期间使用。在生产中,禁用 CSRF 保护或允许网站使用框架可能会带来严重的安全风险。

当控制台的路径已自定义时,PathRequest.toH2Console()也会返回正确的请求匹配器。

9.1.7. 使用 jOOQ

jOOQ 面向对象查询 ( jOOQ ) 是arrow-up-rightData Geekeryarrow-up-right的一款流行产品,它从数据库生成 Java 代码,并允许您通过其流畅的 API 构建类型安全的 SQL 查询。商业版和开源版都可以与 Spring Boot 一起使用。

代码生成

为了使用 jOOQ 类型安全查询,您需要从数据库模式生成 Java 类。您可以按照jOOQ 用户手册arrow-up-right中的说明进行操作。如果您使用jooq-codegen-maven插件并且还使用“父 POM”spring-boot-starter-parent,则可以安全地省略该插件的<version>标签。您还可以使用 Spring Boot 定义的版本变量(例如h2.version)来声明插件的数据库依赖项。以下清单显示了一个示例:

使用 DSLContext

jOOQ提供的Fluent API是通过org.jooq.DSLContext接口发起的。Spring Boot 自动将 DSLContext 配置为 Spring Bean 并将其连接到您应用程序的DataSource。要使用DSLContext,您可以注入它,如以下示例所示:

jOOQ 手册倾向于使用名为create的变量来保存DSLContext.

然后,您可以使用DSLContext来构建查询,如以下示例所示:

jOOQ SQL 方言

除非已配置spring.jooq.sql-dialect属性,否则 Spring Boot 会确定用于数据源的 SQL 方言。如果 Spring Boot 无法检测到方言,它会使用DEFAULT.

Spring Boot 只能自动配置开源版本 jOOQ 支持的方言。

定制jOOQ

可以通过定义您自己的DefaultConfigurationCustomizerbean 来实现更高级的自定义,该 bean 将在创建org.jooq.Configuration @Bean时调用. 这优先于自动配置应用的任何内容。

如果您想完全控制 jOOQ 配置,您也可以创建自己的org.jooq.Configuration @Bean

9.1.8. 使用 R2DBC

反应式关系数据库连接 ( R2DBCarrow-up-right ) 项目为关系数据库带来了反应式编程 API。R2DBC的io.r2dbc.spi.Connection提供了一种使用非阻塞数据库连接的标准方法。连接是通过使用ConnectionFactory提供的,类似于jdbc 中的 DataSource

ConnectionFactory配置由 spring.r2dbc.*中的外部配置属性控制。例如,您可以在application.properties 中声明以下部分:

您不需要指定驱动程序类名,因为 Spring Boot 从 R2DBC 的连接工厂发现中获取驱动程序。

至少应该提供网址。URL 中指定的信息优先于各个属性,即nameusernamepassword池选项。

“操作方法”部分包括有关如何初始化数据库的部分arrow-up-right

要自定义由ConnectionFactory 所创建的连接,即设置您不想(或无法)在中央数据库配置中配置的特定参数,您可以使用ConnectionFactoryOptionsBuilderCustomizer @Bean. 以下示例显示如何手动覆盖数据库端口,而其余选项则取自应用程序配置:

以下示例显示如何设置一些 PostgreSQL 连接选项:

ConnectionFactorybean 可用时,常规 JDBCDataSource自动配置就会停止。如果您想保留 JDBCDataSource自动配置,并且愿意接受在反应式应用程序中使用阻塞 JDBC API 的风险,请在应用程序中的一个@Configuration类添加@Import(DataSourceAutoConfiguration.class)以重新启用它。

嵌入式数据库支持

JDBC 支持arrow-up-right类似,Spring Boot 可以自动配置嵌入式数据库以进行反应式使用。您无需提供任何连接 URL。您只需包含对要使用的嵌入式数据库的构建依赖项,如以下示例所示:

如果您在测试中使用此功能,您可能会注意到,无论您使用的应用程序上下文数量如何,整个测试套件都会重复使用同一个数据库。如果您想确保每个上下文都有一个单独的嵌入式数据库,您应该设置spring.r2dbc.generate-unique-nametrue

使用数据库客户端

DatabaseClient bean是自动配置的,您可以将@Autowire其直接添加到您自己的 bean 中,如以下示例所示:

Spring Data R2DBC 存储库

Spring Data R2DBCarrow-up-right存储库是您可以定义来访问数据的接口。查询是根据您的方法名称自动创建的。例如,CityRepository接口可能声明一个findAllByState(String state)方法来查找给定州下的所有城市。

对于更复杂的查询,您可以使用 Spring Data 的Queryarrow-up-right注释来注释您的方法。

Spring Data 存储库通常从Repositoryarrow-up-rightCrudRepositoryarrow-up-right接口扩展。如果您使用自动配置,则会在自动配置包中arrow-up-right搜索存储库。

以下示例显示了典型的 Spring Data 存储库接口定义:

我们仅仅触及了 Spring Data R2DBC 的皮毛。有关完整的详细信息,请参阅Spring Data R2DBC 参考文档arrow-up-right

最后更新于