Spring Boot包含许多用于处理数据源的启动器。本节回答与这样做有关的问题。

9.1. 配置自定义数据源

要配置自己的DataSource,请在配置中定义@Bean该类型的。Spring Boot可以DataSource在任何需要重用的地方重复使用,包括数据库初始化。如果需要外部化某些设置,则可以将其绑定DataSource到环境(请参阅“ spring-boot-features.html ”)。
以下示例显示如何在Bean中定义数据源:

  1. @Bean
  2. @ConfigurationProperties(prefix="app.datasource")
  3. public DataSource dataSource() {
  4. return new FancyDataSource();
  5. }

以下示例显示如何通过设置属性来定义数据源:
物产
Yaml

  1. app.datasource.url=jdbc:h2:mem:mydb
  2. app.datasource.username=sa
  3. app.datasource.pool-size=30

假定您FancyDataSource具有URL,用户名和池大小的常规JavaBean属性,则在将设置DataSource提供给其他组件之前,将自动绑定这些设置。常规的数据库初始化也会发生(因此的相关子集spring.datasource.*仍可以与您的自定义配置一起使用)。
Spring Boot还提供了一个名为的实用程序生成器类,该类DataSourceBuilder可用于创建标准数据源之一(如果它位于类路径上)。构建器可以根据类路径中可用的内容来检测要使用的一个。它还基于JDBC URL自动检测驱动程序。
以下示例显示如何使用来创建数据源DataSourceBuilder

  1. @Bean
  2. @ConfigurationProperties("app.datasource")
  3. public DataSource dataSource() {
  4. return DataSourceBuilder.create().build();
  5. }

要使用that运行应用程序DataSource,您需要的只是连接信息。还可以提供特定于池的设置。有关更多详细信息,请检查将在运行时使用的实现。
以下示例显示如何通过设置属性来定义JDBC数据源:
物产
Yaml

  1. app.datasource.url=jdbc:mysql://localhost/test
  2. app.datasource.username=dbuser
  3. app.datasource.password=dbpass
  4. app.datasource.pool-size=30

但是,有一个陷阱。由于未公开连接池的实际类型,因此在自定义元数据中不会生成任何键,DataSource并且在IDE中也无法完成操作(因为该DataSource接口未公开任何属性)。另外,如果您碰巧在类路径上有Hikari,则此基本设置将不起作用,因为Hikari没有url属性(但确实具有jdbcUrl属性)。在这种情况下,您必须按照以下方式重写配置:
物产
Yaml

  1. app.datasource.jdbc-url=jdbc:mysql://localhost/test
  2. app.datasource.username=dbuser
  3. app.datasource.password=dbpass
  4. app.datasource.pool-size=30

您可以通过强制连接池使用并返回专用的实现而不是来解决此问题DataSource。您无法在运行时更改实现,但是选项列表将是明确的。
下面的示例演示如何创建一个HikariDataSource具有DataSourceBuilder

  1. @Bean
  2. @ConfigurationProperties("app.datasource")
  3. public HikariDataSource dataSource() {
  4. return DataSourceBuilder.create().type(HikariDataSource.class).build();
  5. }

您甚至可以利用DataSourceProperties为您服务的功能(即,如果没有提供URL,则为默认的嵌入式数据库提供一个有意义的用户名和密码)来走得更远。您可以轻松地DataSourceBuilder从任何DataSourceProperties对象的状态初始化a ,因此您还可以注入Spring Boot自动创建的DataSource。然而,这将配置分为两个命名空间:urlusernamepasswordtype,和driverspring.datasource和您的自定义命名空间中的其余部分(app.datasource)。为避免这种情况,可以DataSourceProperties在自定义名称空间上重新定义一个自定义,如以下示例所示:

  1. @Bean
  2. @Primary
  3. @ConfigurationProperties("app.datasource")
  4. public DataSourceProperties dataSourceProperties() {
  5. return new DataSourceProperties();
  6. }
  7. @Bean
  8. @ConfigurationProperties("app.datasource.configuration")
  9. public HikariDataSource dataSource(DataSourceProperties properties) {
  10. return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
  11. }

默认情况下,该设置使您与Spring Boot为您所做的同步,不同的是,已选择(以代码形式)专用连接池,并且其设置在app.datasource.configuration子名称空间中公开。因为DataSourceProperties正在为您处理url/jdbcUrl转换,所以可以按以下方式配置它:
物产
Yaml

  1. app.datasource.url=jdbc:mysql://localhost/test
  2. app.datasource.username=dbuser
  3. app.datasource.password=dbpass
  4. app.datasource.configuration.maximum-pool-size=30
Spring Boot会将Hikari特定的设置公开给spring.datasource.hikari。本示例使用更通用的configuration子名称空间,因为该示例不支持多个数据源实现。
由于您的自定义配置选择与Hikari一起使用,app.datasource.type因此无效。实际上,构建器会使用您可以在其中设置的任何值进行初始化,然后由调用覆盖.type()

有关更多详细信息,请参见“ Spring Boot功能”部分中的“ spring-boot-features.html ”和DataSourceAutoConfiguration该类。

9.2. 配置两个数据源

如果需要配置多个数据源,则可以应用上一节中介绍的相同技巧。但是,您必须将其中一个DataSource实例标记为@Primary,因为将来各种自动配置都希望能够按类型获取一个。
如果您创建自己的DataSource,则自动配置将退出。在以下示例中,我们提供与自动配置在主数据源上提供的功能完全相同的功能集:

  1. @Bean
  2. @Primary
  3. @ConfigurationProperties("app.datasource.first")
  4. public DataSourceProperties firstDataSourceProperties() {
  5. return new DataSourceProperties();
  6. }
  7. @Bean
  8. @Primary
  9. @ConfigurationProperties("app.datasource.first.configuration")
  10. public HikariDataSource firstDataSource() {
  11. return firstDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
  12. }
  13. @Bean
  14. @ConfigurationProperties("app.datasource.second")
  15. public BasicDataSource secondDataSource() {
  16. return DataSourceBuilder.create().type(BasicDataSource.class).build();
  17. }
firstDataSourceProperties必须标记为,@Primary以便数据库初始化程序功能使用您的副本(如果使用初始化程序)。

这两个数据源也都必须进行高级定制。例如,您可以按以下方式配置它们:
物产
Yaml

  1. app.datasource.first.url=jdbc:mysql://localhost/first
  2. app.datasource.first.username=dbuser
  3. app.datasource.first.password=dbpass
  4. app.datasource.first.configuration.maximum-pool-size=30
  5. app.datasource.second.url=jdbc:mysql://localhost/second
  6. app.datasource.second.username=dbuser
  7. app.datasource.second.password=dbpass
  8. app.datasource.second.max-total=30

您也可以将相同的概念应用于辅助服务器DataSource,如以下示例所示:

  1. @Bean
  2. @Primary
  3. @ConfigurationProperties("app.datasource.first")
  4. public DataSourceProperties firstDataSourceProperties() {
  5. return new DataSourceProperties();
  6. }
  7. @Bean
  8. @Primary
  9. @ConfigurationProperties("app.datasource.first.configuration")
  10. public HikariDataSource firstDataSource() {
  11. return firstDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
  12. }
  13. @Bean
  14. @ConfigurationProperties("app.datasource.second")
  15. public DataSourceProperties secondDataSourceProperties() {
  16. return new DataSourceProperties();
  17. }
  18. @Bean
  19. @ConfigurationProperties("app.datasource.second.configuration")
  20. public BasicDataSource secondDataSource() {
  21. return secondDataSourceProperties().initializeDataSourceBuilder().type(BasicDataSource.class).build();
  22. }

上面的示例在自定义名称空间上配置两个数据源,其逻辑与Spring Boot在自动配置中使用的逻辑相同。请注意,每个configuration子名称空间都根据所选实现提供高级设置。

9.3. 使用Spring数据仓库

Spring Data可以创建@Repository各种类型的接口的实现。只要Spring Boot@Repositories包含在类的同一包(或子包)中,Spring Boot就会为您处理所有这些操作@EnableAutoConfiguration
对于许多应用程序,您所需要做的就是将正确的Spring Data依赖项放在类路径上。spring-boot-starter-data-jpaJPA,spring-boot-starter-data-mongodbMongodb等都有一个。首先,创建一些存储库接口来处理您的@Entity对象。
Spring Boot会@Repository根据@EnableAutoConfiguration找到的内容尝试猜测您定义的位置。要获得更多控制权,请使用@EnableJpaRepositories注释(来自Spring Data JPA)。
有关Spring Data的更多信息,请参见Spring Data项目页面

9.4. 将@Entity定义与Spring配置分开

Spring Boot会@Entity根据@EnableAutoConfiguration找到的内容尝试猜测您定义的位置。要获得更多控制,可以使用@EntityScan注释,如以下示例所示:

  1. @Configuration(proxyBeanMethods = false)
  2. @EnableAutoConfiguration
  3. @EntityScan(basePackageClasses=City.class)
  4. public class Application {
  5. //...
  6. }

9.5. 配置JPA属性

Spring Data JPA已经提供了一些独立于供应商的配置选项(例如用于SQL日志记录的那些),并且Spring Boot将这些选项以及Hibernate的其他一些选项作为外部配置属性公开。其中一些会根据上下文自动检测到,因此您不必进行设置。
spring.jpa.hibernate.ddl-auto是一种特殊情况,因为根据运行时条件,它具有不同的默认值。如果使用嵌入式数据库并且没有模式管理器(例如Liquibase或Flyway)正在处理DataSource,则默认为create-drop。在所有其他情况下,默认为none
JPA提供程序检测到要使用的方言。如果您想自己设置方言,请设置spring.jpa.database-platform属性。
以下示例显示了最常用的设置选项:
物产
Yaml

  1. spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
  2. spring.jpa.show-sql=true

此外,创建spring.jpa.properties.*本地时,所有属性均作为常规JPA属性(前缀被去除)传递EntityManagerFactory

您需要确保在下面定义的名称spring.jpa.properties.*与您的JPA提供程序期望的名称完全匹配。Spring Boot不会尝试对这些条目进行任何形式的宽松绑定。
例如,如果要配置Hibernate的批处理大小,则必须使用spring.jpa.properties.hibernate.jdbc.batch_size。如果您使用其他形式,例如batchSizebatch-size,则Hibernate将不会应用该设置。
如果您需要对Hibernate属性应用高级自定义,请考虑HibernatePropertiesCustomizer在创建之前注册将被调用的bean EntityManagerFactory。这优先于自动配置应用的任何内容。

9.6. 配置休眠命名策略

Hibernate使用两种不同的命名策略将名称从对象模型映射到相应的数据库名称。可以分别通过设置spring.jpa.hibernate.naming.physical-strategyspring.jpa.hibernate.naming.implicit-strategy属性来配置物理和隐式策略实现的标准类名。替代地,如果ImplicitNamingStrategyPhysicalNamingStrategy豆在应用程序上下文是可用的,Hibernate会被自动配置为使用它们。
默认情况下,Spring Boot使用配置物理命名策略SpringPhysicalNamingStrategy。此实现提供了与Hibernate 4相同的表结构:所有点都由下划线替换,骆驼套也由下划线替换。默认情况下,所有表名均以小写形式生成,但是如果您的模式需要它,则可以覆盖该标志。
例如,一个TelephoneNumber实体被映射到telephone_number表。
如果您更喜欢使用Hibernate 5的默认设置,请设置以下属性:
spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
或者,您可以配置以下bean:

  1. @Bean
  2. public PhysicalNamingStrategy physicalNamingStrategy() {
  3. return new PhysicalNamingStrategyStandardImpl();
  4. }

请参阅HibernateJpaAutoConfigurationJpaBaseConfiguration了解更多详细信息。

9.7. 配置Hibernate二级缓存

可以为一系列缓存提供程序配置Hibernate二级缓存。与其将Hibernate配置为再次查找缓存提供程序,不如提供尽可能在上下文中可用的缓存提供程序。
要使用JCache做到这一点,首先要确保它org.hibernate:hibernate-jcache在类路径中可用。然后,添加一个HibernatePropertiesCustomizerbean,如以下示例所示:

  1. @Configuration(proxyBeanMethods = false)
  2. public class HibernateSecondLevelCacheExample {
  3. @Bean
  4. public HibernatePropertiesCustomizer hibernateSecondLevelCacheCustomizer(JCacheCacheManager cacheManager) {
  5. return (properties) -> properties.put(ConfigSettings.CACHE_MANAGER, cacheManager.getCacheManager());
  6. }
  7. }

该定制程序将配置Hibernate以CacheManager使其与应用程序使用的Hibernate相同。也可以使用单独的CacheManager实例。有关详细信息,请参阅《 Hibernate用户指南》

9.8. 在Hibernate组件中使用依赖注入

默认情况下,Spring Boot注册使用的BeanContainer实现,BeanFactory以便转换器和实体侦听器可以使用常规依赖项注入。
您可以通过注册HibernatePropertiesCustomizer删除或更改hibernate.resource.beans.container属性的来禁用或调整此行为。

9.9. 使用自定义EntityManagerFactory

要完全控制的配置EntityManagerFactory,您需要添加一个@Bean名为“ entityManagerFactory”的文件。如果存在这种类型的Bean,Spring Boot自动配置将关闭其实体管理器。

9.10. 使用两个EntityManager

即使默认设置EntityManagerFactory可以正常工作,您也需要定义一个新的,否则,该类型的第二个bean的存在将关闭默认设置。您可以使用EntityManagerBuilderSpring Boot提供的帮助来创建一个。或者,您可以LocalContainerEntityManagerFactoryBean直接使用Spring ORM的Direct,如以下示例所示:

  1. // add two data sources configured as above
  2. @Bean
  3. public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(
  4. EntityManagerFactoryBuilder builder) {
  5. return builder
  6. .dataSource(customerDataSource())
  7. .packages(Customer.class)
  8. .persistenceUnit("customers")
  9. .build();
  10. }
  11. @Bean
  12. public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory(
  13. EntityManagerFactoryBuilder builder) {
  14. return builder
  15. .dataSource(orderDataSource())
  16. .packages(Order.class)
  17. .persistenceUnit("orders")
  18. .build();
  19. }
当您为LocalContainerEntityManagerFactoryBean自己创建一个bean时,在创建自动配置的过程中应用的所有定制都将LocalContainerEntityManagerFactoryBean丢失。例如,在Hibernate的情况下,spring.jpa.hibernate前缀下的任何属性都不会自动应用于LocalContainerEntityManagerFactoryBean。如果您依靠这些属性来配置诸如命名策略或DDL模式之类的东西,则在创建LocalContainerEntityManagerFactoryBeanBean时将需要显式配置。另一方面,如果您使用自动配置来构建Bean ,则将自动应用EntityManagerFactoryBuilder通过所指定的应用于自动配置的属性。 spring.jpa.properties``EntityManagerFactoryBuilder``LocalContainerEntityManagerFactoryBean

上面的配置几乎可以独立工作。要完成图片,您还需要TransactionManagers为两者进行配置EntityManagers。如果将其中一个标记为@Primary,则默认情况下可以JpaTransactionManager在Spring Boot中将其选中。另一个必须显式地注入到新实例中。另外,您也许可以使用跨这两者的JTA事务管理器。
如果使用Spring Data,则需要进行相应的配置@EnableJpaRepositories,如以下示例所示:

  1. @Configuration(proxyBeanMethods = false)
  2. @EnableJpaRepositories(basePackageClasses = Customer.class,
  3. entityManagerFactoryRef = "customerEntityManagerFactory")
  4. public class CustomerConfiguration {
  5. ...
  6. }
  7. @Configuration(proxyBeanMethods = false)
  8. @EnableJpaRepositories(basePackageClasses = Order.class,
  9. entityManagerFactoryRef = "orderEntityManagerFactory")
  10. public class OrderConfiguration {
  11. ...
  12. }

9.11. 使用传统的persistence.xml文件

META-INF/persistence.xml默认情况下,Spring Boot不会搜索或使用。如果您喜欢使用传统的persistence.xml,则需要定义自己@Bean的类型LocalEntityManagerFactoryBean(ID为’entityManagerFactory’)并在其中设置持久性单元名称。
请参阅JpaBaseConfiguration以获取默认设置。

9.12. 使用Spring Data JPA和Mongo存储库

Spring Data JPA和Spring Data Mongo都可以自动Repository为您创建实现。如果它们都存在于类路径中,则可能必须做一些额外的配置以告诉Spring Boot要创建哪个存储库。最明确的方法是使用标准的Spring数据@EnableJpaRepositories@EnableMongoRepositories注释并提供Repository接口的位置。
您还可以使用标记(spring.data.*.repositories.enabledspring.data.*.repositories.type)在外部配置中打开和关闭自动配置的存储库。这样做很有用,例如,在您要关闭Mongo存储库并仍使用自动配置的情况下MongoTemplate
对于其他自动配置的Spring Data存储库类型(Elasticsearch,Solr等),存在相同的障碍和相同的功能。要使用它们,请相应地更改注释和标志的名称。

9.13. 定制Spring Data的Web支持

Spring Data提供了Web支持,简化了Web应用程序中Spring Data存储库的使用。Spring Boot在spring.data.web名称空间中提供了用于自定义其配置的属性。请注意,如果您使用的是Spring Data REST,则必须spring.data.rest改为使用名称空间中的属性。

9.14. 将Spring数据存储库公开为REST端点

Repository如果已为应用程序启用了Spring MVC,Spring Data REST可以为您将实现公开为REST端点。
Spring Boot公开了一组有用的属性(来自spring.data.rest名称空间),用于自定义RepositoryRestConfiguration。如果需要提供其他定制,则应使用RepositoryRestConfigurerBean。

如果您未在custom上指定任何顺序RepositoryRestConfigurer,则该顺序将在一个Spring Boot在内部使用后运行。如果您需要指定一个订单,请确保它大于0。

9.15. 配置由JPA使用的组件

如果要配置JPA使用的组件,则需要确保在JPA之前初始化该组件。当组件被自动配置后,Spring Boot会为您处理。例如,当自动配置Flyway时,会将Hibernate配置为依赖Flyway,这样Flyway就有机会在Hibernate尝试使用数据库之前对其进行初始化。
如果您自己配置组件,则可以使用EntityManagerFactoryDependsOnPostProcessor子类作为设置必要依赖项的便捷方法。例如,如果将Hibernate Search与Elasticsearch一起用作其索引管理器,则EntityManagerFactory必须将任何bean配置为依赖于该elasticsearchClientbean,如以下示例所示:

  1. /**
  2. * {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that
  3. * {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean.
  4. */
  5. @Component
  6. static class ElasticsearchEntityManagerFactoryDependsOnPostProcessor
  7. extends EntityManagerFactoryDependsOnPostProcessor {
  8. ElasticsearchEntityManagerFactoryDependsOnPostProcessor() {
  9. super("elasticsearchClient");
  10. }
  11. }

9.16. 使用两个数据源配置jOOQ

如果需要将jOOQ与多个数据源一起使用,则应该DSLContext为每个数据源创建自己的jOOQ 。有关更多详细信息,请参阅JooqAutoConfiguration

特别是,JooqExceptionTranslator并且SpringTransactionProvider可以重复使用,以提供与单个自动配置相似的功能DataSource