- 9.1. 配置自定义数据源
- 9.2. 配置两个数据源
- 9.3. 使用Spring数据仓库
- 9.4. 将@Entity定义与Spring配置分开
- 9.5. 配置JPA属性
- 9.6. 配置休眠命名策略
- 9.7. 配置Hibernate二级缓存
- 9.8. 在Hibernate组件中使用依赖注入
- 9.9. 使用自定义EntityManagerFactory
- 9.10. 使用两个EntityManager
- 9.11. 使用传统的persistence.xml文件
- 9.12. 使用Spring Data JPA和Mongo存储库
- 9.13. 定制Spring Data的Web支持
- 9.14. 将Spring数据存储库公开为REST端点
- 9.15. 配置由JPA使用的组件
- 9.16. 使用两个数据源配置jOOQ
Spring Boot包含许多用于处理数据源的启动器。本节回答与这样做有关的问题。
9.1. 配置自定义数据源
要配置自己的DataSource
,请在配置中定义@Bean
该类型的。Spring Boot可以DataSource
在任何需要重用的地方重复使用,包括数据库初始化。如果需要外部化某些设置,则可以将其绑定DataSource
到环境(请参阅“ spring-boot-features.html ”)。
以下示例显示如何在Bean中定义数据源:
@Bean
@ConfigurationProperties(prefix="app.datasource")
public DataSource dataSource() {
return new FancyDataSource();
}
以下示例显示如何通过设置属性来定义数据源:
物产
Yaml
app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30
假定您FancyDataSource
具有URL,用户名和池大小的常规JavaBean属性,则在将设置DataSource
提供给其他组件之前,将自动绑定这些设置。常规的数据库初始化也会发生(因此的相关子集spring.datasource.*
仍可以与您的自定义配置一起使用)。
Spring Boot还提供了一个名为的实用程序生成器类,该类DataSourceBuilder
可用于创建标准数据源之一(如果它位于类路径上)。构建器可以根据类路径中可用的内容来检测要使用的一个。它还基于JDBC URL自动检测驱动程序。
以下示例显示如何使用来创建数据源DataSourceBuilder
:
@Bean
@ConfigurationProperties("app.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
要使用that运行应用程序DataSource
,您需要的只是连接信息。还可以提供特定于池的设置。有关更多详细信息,请检查将在运行时使用的实现。
以下示例显示如何通过设置属性来定义JDBC数据源:
物产
Yaml
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
但是,有一个陷阱。由于未公开连接池的实际类型,因此在自定义元数据中不会生成任何键,DataSource
并且在IDE中也无法完成操作(因为该DataSource
接口未公开任何属性)。另外,如果您碰巧在类路径上有Hikari,则此基本设置将不起作用,因为Hikari没有url
属性(但确实具有jdbcUrl
属性)。在这种情况下,您必须按照以下方式重写配置:
物产
Yaml
app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
您可以通过强制连接池使用并返回专用的实现而不是来解决此问题DataSource
。您无法在运行时更改实现,但是选项列表将是明确的。
下面的示例演示如何创建一个HikariDataSource
具有DataSourceBuilder
:
@Bean
@ConfigurationProperties("app.datasource")
public HikariDataSource dataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
您甚至可以利用DataSourceProperties
为您服务的功能(即,如果没有提供URL,则为默认的嵌入式数据库提供一个有意义的用户名和密码)来走得更远。您可以轻松地DataSourceBuilder
从任何DataSourceProperties
对象的状态初始化a ,因此您还可以注入Spring Boot自动创建的DataSource。然而,这将配置分为两个命名空间:url
,username
,password
,type
,和driver
上spring.datasource
和您的自定义命名空间中的其余部分(app.datasource
)。为避免这种情况,可以DataSourceProperties
在自定义名称空间上重新定义一个自定义,如以下示例所示:
@Bean
@Primary
@ConfigurationProperties("app.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("app.datasource.configuration")
public HikariDataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
默认情况下,该设置使您与Spring Boot为您所做的同步,不同的是,已选择(以代码形式)专用连接池,并且其设置在app.datasource.configuration
子名称空间中公开。因为DataSourceProperties
正在为您处理url
/jdbcUrl
转换,所以可以按以下方式配置它:
物产
Yaml
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
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
,则自动配置将退出。在以下示例中,我们提供与自动配置在主数据源上提供的功能完全相同的功能集:
@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("app.datasource.first.configuration")
public HikariDataSource firstDataSource() {
return firstDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
@ConfigurationProperties("app.datasource.second")
public BasicDataSource secondDataSource() {
return DataSourceBuilder.create().type(BasicDataSource.class).build();
}
firstDataSourceProperties 必须标记为,@Primary 以便数据库初始化程序功能使用您的副本(如果使用初始化程序)。 |
|
---|---|
这两个数据源也都必须进行高级定制。例如,您可以按以下方式配置它们:
物产
Yaml
app.datasource.first.url=jdbc:mysql://localhost/first
app.datasource.first.username=dbuser
app.datasource.first.password=dbpass
app.datasource.first.configuration.maximum-pool-size=30
app.datasource.second.url=jdbc:mysql://localhost/second
app.datasource.second.username=dbuser
app.datasource.second.password=dbpass
app.datasource.second.max-total=30
您也可以将相同的概念应用于辅助服务器DataSource
,如以下示例所示:
@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("app.datasource.first.configuration")
public HikariDataSource firstDataSource() {
return firstDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
@ConfigurationProperties("app.datasource.second")
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("app.datasource.second.configuration")
public BasicDataSource secondDataSource() {
return secondDataSourceProperties().initializeDataSourceBuilder().type(BasicDataSource.class).build();
}
上面的示例在自定义名称空间上配置两个数据源,其逻辑与Spring Boot在自动配置中使用的逻辑相同。请注意,每个configuration
子名称空间都根据所选实现提供高级设置。
9.3. 使用Spring数据仓库
Spring Data可以创建@Repository
各种类型的接口的实现。只要Spring Boot@Repositories
包含在类的同一包(或子包)中,Spring Boot就会为您处理所有这些操作@EnableAutoConfiguration
。
对于许多应用程序,您所需要做的就是将正确的Spring Data依赖项放在类路径上。spring-boot-starter-data-jpa
JPA,spring-boot-starter-data-mongodb
Mongodb等都有一个。首先,创建一些存储库接口来处理您的@Entity
对象。
Spring Boot会@Repository
根据@EnableAutoConfiguration
找到的内容尝试猜测您定义的位置。要获得更多控制权,请使用@EnableJpaRepositories
注释(来自Spring Data JPA)。
有关Spring Data的更多信息,请参见Spring Data项目页面。
9.4. 将@Entity定义与Spring配置分开
Spring Boot会@Entity
根据@EnableAutoConfiguration
找到的内容尝试猜测您定义的位置。要获得更多控制,可以使用@EntityScan
注释,如以下示例所示:
@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EntityScan(basePackageClasses=City.class)
public class Application {
//...
}
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
spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
spring.jpa.show-sql=true
此外,创建spring.jpa.properties.*
本地时,所有属性均作为常规JPA属性(前缀被去除)传递EntityManagerFactory
。
您需要确保在下面定义的名称spring.jpa.properties.* 与您的JPA提供程序期望的名称完全匹配。Spring Boot不会尝试对这些条目进行任何形式的宽松绑定。例如,如果要配置Hibernate的批处理大小,则必须使用 spring.jpa.properties.hibernate.jdbc.batch_size 。如果您使用其他形式,例如batchSize 或batch-size ,则Hibernate将不会应用该设置。 |
|
---|---|
如果您需要对Hibernate属性应用高级自定义,请考虑HibernatePropertiesCustomizer 在创建之前注册将被调用的bean EntityManagerFactory 。这优先于自动配置应用的任何内容。 |
|
---|---|
9.6. 配置休眠命名策略
Hibernate使用两种不同的命名策略将名称从对象模型映射到相应的数据库名称。可以分别通过设置spring.jpa.hibernate.naming.physical-strategy
和spring.jpa.hibernate.naming.implicit-strategy
属性来配置物理和隐式策略实现的标准类名。替代地,如果ImplicitNamingStrategy
或PhysicalNamingStrategy
豆在应用程序上下文是可用的,Hibernate会被自动配置为使用它们。
默认情况下,Spring Boot使用配置物理命名策略SpringPhysicalNamingStrategy
。此实现提供了与Hibernate 4相同的表结构:所有点都由下划线替换,骆驼套也由下划线替换。默认情况下,所有表名均以小写形式生成,但是如果您的模式需要它,则可以覆盖该标志。
例如,一个TelephoneNumber
实体被映射到telephone_number
表。
如果您更喜欢使用Hibernate 5的默认设置,请设置以下属性:
spring.jpa.hibernate.naming.physical-strategy = org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
或者,您可以配置以下bean:
@Bean
public PhysicalNamingStrategy physicalNamingStrategy() {
return new PhysicalNamingStrategyStandardImpl();
}
请参阅HibernateJpaAutoConfiguration
和JpaBaseConfiguration
了解更多详细信息。
9.7. 配置Hibernate二级缓存
可以为一系列缓存提供程序配置Hibernate二级缓存。与其将Hibernate配置为再次查找缓存提供程序,不如提供尽可能在上下文中可用的缓存提供程序。
要使用JCache做到这一点,首先要确保它org.hibernate:hibernate-jcache
在类路径中可用。然后,添加一个HibernatePropertiesCustomizer
bean,如以下示例所示:
@Configuration(proxyBeanMethods = false)
public class HibernateSecondLevelCacheExample {
@Bean
public HibernatePropertiesCustomizer hibernateSecondLevelCacheCustomizer(JCacheCacheManager cacheManager) {
return (properties) -> properties.put(ConfigSettings.CACHE_MANAGER, cacheManager.getCacheManager());
}
}
该定制程序将配置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的存在将关闭默认设置。您可以使用EntityManagerBuilder
Spring Boot提供的帮助来创建一个。或者,您可以LocalContainerEntityManagerFactoryBean
直接使用Spring ORM的Direct,如以下示例所示:
// add two data sources configured as above
@Bean
public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(customerDataSource())
.packages(Customer.class)
.persistenceUnit("customers")
.build();
}
@Bean
public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(orderDataSource())
.packages(Order.class)
.persistenceUnit("orders")
.build();
}
当您为LocalContainerEntityManagerFactoryBean 自己创建一个bean时,在创建自动配置的过程中应用的所有定制都将LocalContainerEntityManagerFactoryBean 丢失。例如,在Hibernate的情况下,spring.jpa.hibernate 前缀下的任何属性都不会自动应用于LocalContainerEntityManagerFactoryBean 。如果您依靠这些属性来配置诸如命名策略或DDL模式之类的东西,则在创建LocalContainerEntityManagerFactoryBean Bean时将需要显式配置。另一方面,如果您使用自动配置来构建Bean ,则将自动应用EntityManagerFactoryBuilder 通过所指定的应用于自动配置的属性。 spring.jpa.properties``EntityManagerFactoryBuilder``LocalContainerEntityManagerFactoryBean |
|
---|---|
上面的配置几乎可以独立工作。要完成图片,您还需要TransactionManagers
为两者进行配置EntityManagers
。如果将其中一个标记为@Primary
,则默认情况下可以JpaTransactionManager
在Spring Boot中将其选中。另一个必须显式地注入到新实例中。另外,您也许可以使用跨这两者的JTA事务管理器。
如果使用Spring Data,则需要进行相应的配置@EnableJpaRepositories
,如以下示例所示:
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Customer.class,
entityManagerFactoryRef = "customerEntityManagerFactory")
public class CustomerConfiguration {
...
}
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Order.class,
entityManagerFactoryRef = "orderEntityManagerFactory")
public class OrderConfiguration {
...
}
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.enabled
和spring.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
。如果需要提供其他定制,则应使用RepositoryRestConfigurer
Bean。
如果您未在custom上指定任何顺序RepositoryRestConfigurer ,则该顺序将在一个Spring Boot在内部使用后运行。如果您需要指定一个订单,请确保它大于0。 |
|
---|---|
9.15. 配置由JPA使用的组件
如果要配置JPA使用的组件,则需要确保在JPA之前初始化该组件。当组件被自动配置后,Spring Boot会为您处理。例如,当自动配置Flyway时,会将Hibernate配置为依赖Flyway,这样Flyway就有机会在Hibernate尝试使用数据库之前对其进行初始化。
如果您自己配置组件,则可以使用EntityManagerFactoryDependsOnPostProcessor
子类作为设置必要依赖项的便捷方法。例如,如果将Hibernate Search与Elasticsearch一起用作其索引管理器,则EntityManagerFactory
必须将任何bean配置为依赖于该elasticsearchClient
bean,如以下示例所示:
/**
* {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that
* {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean.
*/
@Component
static class ElasticsearchEntityManagerFactoryDependsOnPostProcessor
extends EntityManagerFactoryDependsOnPostProcessor {
ElasticsearchEntityManagerFactoryDependsOnPostProcessor() {
super("elasticsearchClient");
}
}
9.16. 使用两个数据源配置jOOQ
如果需要将jOOQ与多个数据源一起使用,则应该DSLContext
为每个数据源创建自己的jOOQ 。有关更多详细信息,请参阅JooqAutoConfiguration。
特别是,JooqExceptionTranslator 并且SpringTransactionProvider 可以重复使用,以提供与单个自动配置相似的功能DataSource 。 |
|
---|---|