Data Access
Spring Boot 包含许多用于处理数据源的启动器。本节解答了与之相关的问题。
Configure a Custom DataSource
要配置你自己的 DataSource
,请在你的配置中定义该类型的 @Bean
。Spring Boot 在任何需要它的位置重用你的 DataSource
,包括数据库初始化。如果你需要将一些设置外部化,你可以将你的 DataSource
绑定到环境(请参阅 “Third-party Configuration”)。
以下示例展示了如何在 Bean 中定义数据源:
以下示例展示了如何通过设置属性定义数据源:
app: datasource: url: "jdbc:h2:mem:mydb" username: "sa" pool-size: 30
假设 SomeDataSource
具有 URL、用户名和池大小的常规 JavaBean 属性,这些设置会在 DataSource
可供其他组件使用之前自动绑定。
Spring Boot 还提供了一个名为 DataSourceBuilder
的实用程序构建器类,可以用它创建一个标准数据源(如果它在类路径上)。构建器可以根据类路径上可用的内容检测要使用哪一个。它还根据 JDBC URL 自动检测驱动程序。
以下示例展示了如何使用 DataSourceBuilder
创建数据源:
要使用该 DataSource
运行应用程序,你只需要连接信息。还可以提供池特定的设置。详细情况请查看将在运行时使用的实现。
以下示例展示了如何通过设置属性定义 JDBC 数据源:
app: datasource: url: "jdbc:mysql://localhost/test" username: "dbuser" password: "dbpass" pool-size: 30
但是,有个问题。因为实际的连接池类型未显示,所以在你的自定义 DataSource
的元数据中未生成任何键,IDE 中也没有自动完成(因为 DataSource
接口不显示任何属性)。此外,如果你碰巧在类路径上放置了 Hikari,此基本设置无效,因为 Hikari 没有 url
属性(但有 jdbcUrl
属性)。在这种情况下,你必须按如下方式重写配置:
app: datasource: jdbc-url: "jdbc:mysql://localhost/test" username: "dbuser" password: "dbpass" pool-size: 30
你可以通过强制连接池使用并返回专用的实现(而非 DataSource
)来修复此问题。你无法在运行时更改实现,但选项列表将明确显示。
以下示例展示了如何使用 DataSourceBuilder
创建 HikariDataSource
:
您甚至可以通过利用 DataSourceProperties
为您完成的任务进一步深入,即,如果未提供 URL,则提供具有合理用户名和密码的默认嵌入数据库。您可以轻松从任何 DataSourceProperties
对象的状态中初始化 DataSourceBuilder
,因此您还可以注入 Spring Boot 创建的数据源。但是,这会将您的配置分成两个名称空间:url
、username
、password
、type
和 driver
在 spring.datasource
上,其余在您的自定义名称空间 (app.datasource
) 中。为了避免这种情况,您可以在您的自定义名称空间上重新定义一个自定义 DataSourceProperties
,如下例所示:
此设置使您 in sync 与 Spring Boot 默认为您执行的任务保持一致,只不过(在代码中)选择了专用连接池,其设置在 app.datasource.configuration
子名称空间中公开。由于 DataSourceProperties
会为您处理 url
/jdbcUrl
翻译,因此您可以按如下方式配置它:
app: datasource: url: "jdbc:mysql://localhost/test" username: "dbuser" password: "dbpass" configuration: maximum-pool-size: 30
Spring Boot 将向 |
因为您的自定义配置选择了 Hikari,所以 |
请参阅 “Spring Boot features” 部分中的 “Configure a DataSource” 和 {code-spring-boot-autoconfigure-src}/jdbc/DataSourceAutoConfiguration.java[DataSourceAutoConfiguration
] 类以了解更多详情。
Configure Two DataSources
如果您需要配置多个数据源,您可以应用上一节中所述的相同技巧。不过,您必须将其中一个 DataSource
实例标记为 @Primary
,因为下游的各种自动配置期望能够按类型获取一个。
如果您创建了自己的 DataSource
,则自动配置将退避。在以下示例中,我们为 exact 提供与自动配置在主数据源上提供的相同功能集:
|
这两个数据源都绑定用于高级自定义。例如,您可以按如下方式配置它们:
app: datasource: first: url: "jdbc:mysql://localhost/first" username: "dbuser" password: "dbpass" configuration: maximum-pool-size: 30 second: url: "jdbc:mysql://localhost/second" username: "dbuser" password: "dbpass" max-total: 30
您也可以将相同的概念应用到辅助 DataSource
中,如下例所示:
前一个示例使用与 Spring Boot 在自动配置中使用的相同逻辑在自定义名称空间上配置两个数据源。请注意,每个 configuration
子名称空间都根据所选实现提供高级设置。
Use Spring Data Repositories
Spring Data 可以创建各种 @Repository
界面实现。Spring Boot 为您处理所有这些,只要这些 @Repository
注释包含在其中一个 auto-configuration packages 中即可,通常是标注有 @SpringBootApplication
或 @EnableAutoConfiguration
的主应用程序类的包(或子包)。
对于许多应用程序,您只需要将正确的 Spring Data 依赖项放在类路径上。有一个 spring-boot-starter-data-jpa
用以处理 JPA,一个 spring-boot-starter-data-mongodb
用以处理 MongoDB,以及各种其他针对受支持技术的 Starter。要开始使用,创建一些存储库界面来处理 @Entity
对象。
Spring Boot 通过扫描 auto-configuration packages 来确定您的 @Repository
定义的位置。若要进行更多控制,请使用来自 Spring Data 的 @Enable…Repositories
注释。
有关 Spring Data 的更多信息,请参阅 {url-spring-data-site}[Spring Data 项目页面]。
Separate @Entity Definitions from Spring Configuration
Spring Boot 会扫描 auto-configuration packages 来确定 @Entity
定义的位置。如以下示例所示,要进行更多的控制,可以使用 @EntityScan
注解:
Configure JPA Properties
Spring Data JPA 已提供了一些与供应商无关的配置选项(例如 SQL 日志记录选项),Spring Boot 将这些选项和一些 Hibernate 选项作为外部配置属性公开。其中的部分选项会根据上下文自动检测,因此您无需设置这些选项。
spring.jpa.hibernate.ddl-auto
是特殊情况,因为它根据运行时条件有不同的默认值。如果使用了嵌入式数据库,并且没有架构管理器(例如 Liquibase 或 Flyway)处理 DataSource
,则默认值为 create-drop
。在所有其他情况下,默认值为 none
。
方言由 JPA 供应商检测。如果您希望自己设置方言,请设置 configprop:spring.jpa.database-platform[] 属性。
以下示例显示最常见的设置选项:
spring: jpa: hibernate: naming: physical-strategy: "com.example.MyPhysicalNamingStrategy" show-sql: true
此外,在创建 local EntityManagerFactory
时,spring.jpa.properties.*
中的所有属性将作为正常的 JPA 属性传递下来(剥离前缀)。
你必须确保 spring.jpa.properties.*
下定义的名称与 JPA 提供程序期望的完全匹配。Spring Boot 不会对这些条目尝试任何形式的松散绑定。
例如,如果你想配置 Hibernate 的批处理大小,你必须使用 spring.jpa.properties.hibernate.jdbc.batch_size
。如果你使用其他形式,比如 batchSize
或者 batch-size
,Hibernate 将不会应用这个设置。
如果你需要对 Hibernate 属性应用高级自定义,请考虑注册一个 |
Configure Hibernate Naming Strategy
Hibernate 使用 {url-hibernate-userguide}#naming[两种不同的命名策略] 将对象模型中的名称映射到相应的数据库名称。可以分别通过设置 spring.jpa.hibernate.naming.physical-strategy
和 spring.jpa.hibernate.naming.implicit-strategy
属性来配置物理策略和隐式策略实现的完全限定类名。或者,如果 ImplicitNamingStrategy
或 PhysicalNamingStrategy
bean 在应用程序上下文中可用,Hibernate 将被自动配置为使用它们。
默认情况下,Spring Boot 使用 CamelCaseToUnderscoresNamingStrategy
配置物理命名策略。使用这个策略,所有的点都被下划线替换,驼峰式命名也同样被下划线替换。此外,默认情况下,所有表格名称都生成小写。例如,一个 TelephoneNumber
实体被映射到 telephone_number
表格。如果你的架构需要混合大小写标识符,请定义一个自定义 CamelCaseToUnderscoresNamingStrategy
bean,如下例所示:
如果你更愿意使用 Hibernate 的默认值,请设置以下属性:
spring: jpa: hibernate: naming: physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
或者,你可以配置以下 bean:
有关更多详细信息,请参阅 {code-spring-boot-autoconfigure-src}/orm/jpa/HibernateJpaAutoConfiguration.java[HibernateJpaAutoConfiguration
] 和 {code-spring-boot-autoconfigure-src}/orm/jpa/JpaBaseConfiguration.java[JpaBaseConfiguration
]。
Configure Hibernate Second-Level Caching
Hibernate {url-hibernate-userguide}#caching[二级缓存] 可以为一系列缓存提供程序配置。与其配置 Hibernate 再次查找缓存提供程序,更好的办法是尽可能在上下文中提供一个可用的提供程序。
要使用 JCache 来进行此操作,首先确保 org.hibernate.orm:hibernate-jcache
在类路径上可用。然后,添加一个 HibernatePropertiesCustomizer
bean,如下例所示:
此自定义程序将配置 Hibernate 以使用与应用程序所用的相同的 CacheManager
。也可以使用单独 CacheManager
实例。有关详细信息,请参阅 {url-hibernate-userguide}#caching-provider-jcache[Hibernate 用户指南]。
Use Dependency Injection in Hibernate Components
默认情况下,Spring Boot 注册了一个 BeanContainer
实现,它使用 BeanFactory
,以便转换器和实体侦听器可以使用常规依赖项注入。
可以通过注册 HibernatePropertiesCustomizer
禁用或调整此行为,该 HibernatePropertiesCustomizer
将移除或更改 hibernate.resource.beans.container
属性。
Use a Custom EntityManagerFactory
要完全控制 EntityManagerFactory
的配置,则需要添加名为 '`entityManagerFactory’ 的 @Bean
。Spring Boot 自动配置在存在此类型的 bean 时关闭其实体管理器。
Using Multiple EntityManagerFactories
如果您需要对多个数据源使用 JPA,则可能需要每个数据源一个 EntityManagerFactory
。Spring ORM 的 LocalContainerEntityManagerFactoryBean
允许您按照自己的需要配置 EntityManagerFactory
。您还可以重用 JpaProperties
为每个 EntityManagerFactory
绑定设置,如下例所示:
上面的示例使用名为 firstDataSource
的 DataSource
bean 创建 EntityManagerFactory
。它扫描与 Order
在同一包中的实体。使用 app.first.jpa
命名空间映射其他 JPA 属性是可能的。
当您自己创建 |
您应为需要的任何其他数据源提供类似配置以获取 JPA 访问权限。为完成此图片,您还需要为每个 EntityManagerFactory
配置一个 JpaTransactionManager
。或者,您可能可以使用跨越这两个来源的 JTA 事务管理器。
如果您使用 Spring Data,则需要相应地配置 @EnableJpaRepositories
,如下例所示:
Use a Traditional persistence.xml File
默认情况下,Spring Boot 不会搜索或使用 META-INF/persistence.xml
。如果您更喜欢使用传统 persistence.xml
,则需要定义自己的类型为 LocalEntityManagerFactoryBean
(ID 为 '`entityManagerFactory’)的 @Bean
,并在那里设置持久化单元名称。
有关默认设置,请参阅 {code-spring-boot-autoconfigure-src}/orm/jpa/JpaBaseConfiguration.java[JpaBaseConfiguration
]。
Use Spring Data JPA and Mongo Repositories
Spring Data JPA 和 Spring Data Mongo 均可自动为您创建 Repository
实现。如果它们都存在于类路径中,则可能需要做一些额外的配置,以告知 Spring Boot 创建哪些存储库。实现此目标的最明确方法是使用标准的 Spring Data @EnableJpaRepositories
和 @EnableMongoRepositories
注释,并提供 Repository
界面的位置。
您还可以使用一些标志 (spring.data..repositories.enabled
and spring.data..repositories.type
) 在外部配置中开启和关闭自动配置的存储库。这样做很有用,例如,如果您想关闭 Mongo 存储库,但仍使用自动配置的 MongoTemplate
。
对于其他自动配置的 Spring Data 存储库类型(Elasticsearch、Redis 等),存在相同的障碍和相同的功能。要对它们进行处理,请相应地更改注释和标志的名称。
Customize Spring Data’s Web Support
Spring Data 提供 Web 支持,简化了在 Web 应用程序中使用 Spring Data 存储库。Spring Boot 在 spring.data.web
命名空间中提供属性,用于自定义其配置。请注意,如果您使用 Spring Data REST,则必须改为使用 spring.data.rest
命名空间中的属性。
Expose Spring Data Repositories as REST Endpoint
如果已为应用程序启用了 Spring MVC,Spring Data REST 可以将 Repository
实现公开为 REST 端点。
Spring Boot 公开了来自 spring.data.rest
命名空间的一组有用的属性,用来自定义 {url-spring-data-rest-javadoc}/org/springframework/data/rest/core/config/RepositoryRestConfiguration.html[RepositoryRestConfiguration
].如果你需要提供其他自定义,则应使用 {url-spring-data-rest-javadoc}/org/springframework/data/rest/webmvc/config/RepositoryRestConfigurer.html[RepositoryRestConfigurer
] bean。
如果你未在自己的 |
Configure a Component that is Used by JPA
如果你要配置 JPA 使用的组件,那么你需要确保该组件在 JPA 之前初始化。当组件自动配置时,Spring Boot 会为你处理此操作。例如,当 Flyway 自动配置时,Hibernate 会配置为依赖于 Flyway,以便在 Hibernate 尝试使用它之前 Flyway 有机会初始化数据库。
如果你自己配置组件,你可以使用 EntityManagerFactoryDependsOnPostProcessor
子类,这是设置必需依赖项的便利方式。例如,如果你将 Hibernate Search 与 Elasticsearch 一起用作其索引管理器,则必须将所有 EntityManagerFactory
bean 配置为依赖于 elasticsearchClient
bean,如下面的示例所示: