对于最新的稳定版本,请使用 Spring Boot 3.5.5! |
数据访问
Spring Boot 包括许多用于处理数据源的Starters。 本节回答与执行此作相关的问题。
配置自定义数据源
配置您自己的DataSource
,定义一个@Bean
配置中的该类型。
Spring Boot 重用了DataSource
任何需要的地方,包括数据库初始化。
如果需要外部化某些设置,可以绑定DataSource
到环境(请参阅第三方配置)。
以下示例显示了如何在 Bean 中定义数据源:
-
Java
-
Kotlin
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties(prefix = "app.datasource")
public SomeDataSource dataSource() {
return new SomeDataSource();
}
}
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties(prefix = "app.datasource")
fun dataSource(): SomeDataSource {
return SomeDataSource()
}
}
以下示例演示如何通过设置数据源的属性来定义数据源:
-
Properties
-
YAML
app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30
app:
datasource:
url: "jdbc:h2:mem:mydb"
username: "sa"
pool-size: 30
假设SomeDataSource
具有 URL、用户名和池大小的常规 JavaBean 属性,这些设置在DataSource
可用于其他组件。
Spring Boot 还提供了一个实用程序构建器类,称为DataSourceBuilder
,可用于创建标准数据源之一(如果它在类路径上)。
构建器可以根据类路径上可用的内容来检测要使用哪一个。
它还会根据 JDBC URL 自动检测驱动程序。
以下示例演示如何使用DataSourceBuilder
:
-
Java
-
Kotlin
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties("app.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
}
import javax.sql.DataSource
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties("app.datasource")
fun dataSource(): DataSource {
return DataSourceBuilder.create().build()
}
}
要运行该应用DataSource
,您所需要的只是连接信息。
还可以提供特定于池的设置。
检查将在运行时使用的实现以了解更多详细信息。
以下示例显示了如何通过设置属性来定义 JDBC 数据源:
-
Properties
-
YAML
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
app:
datasource:
url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
pool-size: 30
但是,由于该方法的DataSource
返回类型。
这会隐藏连接池的实际类型,因此不会为自定义生成任何配置属性元数据DataSource
并且您的 IDE 中没有可用的自动完成功能。
要解决此问题,请使用构建器的type(Class)
指定类型的方法DataSource
以生成并更新方法的返回类型。
例如,下面演示了如何创建HikariDataSource
跟DataSourceBuilder
:
-
Java
-
Kotlin
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties("app.datasource")
public HikariDataSource dataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
import com.zaxxer.hikari.HikariDataSource
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties("app.datasource")
fun dataSource(): HikariDataSource {
return DataSourceBuilder.create().type(HikariDataSource::class.java).build()
}
}
不幸的是,这个基本设置不起作用,因为 Hikari 没有url
财产。
相反,它有一个jdbc-url
属性,这意味着您必须按如下方式重写配置:
-
Properties
-
YAML
app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
app:
datasource:
jdbc-url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
pool-size: 30
要解决此问题,请使用DataSourceProperties
这将处理url
自jdbc-url
为您翻译。
您可以初始化一个DataSourceBuilder
从任何状态DataSourceProperties
对象使用其initializeDataSourceBuilder()
方法。
您可以注入DataSourceProperties
但是,Spring Boot 会自动创建,这将拆分您的配置spring.datasource.*
和app.datasource.*
.
为避免这种情况,请定义自定义DataSourceProperties
使用自定义配置属性前缀,如以下示例所示:
-
Java
-
Kotlin
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {
@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();
}
}
import com.zaxxer.hikari.HikariDataSource
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary
@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {
@Bean
@Primary
@ConfigurationProperties("app.datasource")
fun dataSourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Bean
@ConfigurationProperties("app.datasource.configuration")
fun dataSource(properties: DataSourceProperties): HikariDataSource {
return properties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
}
}
此设置等同于 Spring Boot 默认为您执行的作,只是池的类型在代码中指定,并且其设置公开为app.datasource.configuration.*
性能。DataSourceProperties
照顾url
自jdbc-url
translation,因此您可以按如下方式配置它:
-
Properties
-
YAML
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.configuration.maximum-pool-size=30
app:
datasource:
url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
configuration:
maximum-pool-size: 30
请注意,由于自定义配置在代码中指定应使用 Hikari,app.datasource.type
不会有任何效果。
如支持的连接池中所述,DataSourceBuilder
支持多个不同的连接池。
要使用 Hikari 以外的池,请将其添加到类路径中,使用type(Class)
方法来指定要使用的池类,并更新@Bean
方法的返回类型。
这还将为所选的特定连接池提供配置属性元数据。
Spring Boot 将 Hikari 特定设置公开给spring.datasource.hikari .
此示例使用更通用的configuration sub 命名空间,因为示例不支持多个数据源实现。 |
请参阅配置数据源和DataSourceAutoConfiguration
class 了解更多详情。
配置两个数据源
要定义附加DataSource
,可以使用与上一节类似的方法。
一个关键的区别是DataSource
@Bean
必须使用defaultCandidate=false
.
这可以防止自动配置的DataSource
从退缩。
Spring Framework 参考文档更详细地描述了此功能。 |
要允许额外的DataSource
要注入到需要的地方,还要用@Qualifier
如以下示例所示:
-
Java
-
Kotlin
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyAdditionalDataSourceConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource")
public HikariDataSource secondDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
import com.zaxxer.hikari.HikariDataSource
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyAdditionalDataSourceConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource")
fun secondDataSource(): HikariDataSource {
return DataSourceBuilder.create().type(HikariDataSource::class.java).build()
}
}
要消耗额外的DataSource
,用相同的@Qualifier
.
自动配置的数据源和其他数据源可以按如下方式配置:
-
Properties
-
YAML
spring.datasource.url=jdbc:mysql://localhost/first
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.configuration.maximum-pool-size=30
app.datasource.url=jdbc:mysql://localhost/second
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.max-total=30
spring:
datasource:
url: "jdbc:mysql://localhost/first"
username: "dbuser"
password: "dbpass"
configuration:
maximum-pool-size: 30
app:
datasource:
url: "jdbc:mysql://localhost/second"
username: "dbuser"
password: "dbpass"
max-total: 30
更高级的、特定于实现的自动配置配置DataSource
可通过spring.datasource.configuration.*
性能。
您可以将相同的概念应用于附加的DataSource
同样,如以下示例所示:
-
Java
-
Kotlin
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyCompleteAdditionalDataSourceConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource")
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource.configuration")
public HikariDataSource secondDataSource(
@Qualifier("secondDataSourceProperties") DataSourceProperties secondDataSourceProperties) {
return secondDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
}
import com.zaxxer.hikari.HikariDataSource
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyCompleteAdditionalDataSourceConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource")
fun secondDataSourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource.configuration")
fun secondDataSource(secondDataSourceProperties: DataSourceProperties): HikariDataSource {
return secondDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
}
}
前面的示例使用与 Spring Boot 在自动配置中使用的相同逻辑来配置其他数据源。
请注意,app.datasource.configuration.*
属性根据所选实现提供高级设置。
与配置单个自定义一样DataSource
,其中一个或两个DataSource
可以使用type(Class)
方法DataSourceBuilder
.
有关支持的类型的详细信息,请参阅支持的连接池。
使用 Spring Data Repositories
Spring Data 可以创建Repository
各种口味的界面。
Spring Boot 会为您处理所有这些,只要这些Repository
实现包含在其中一个自动配置包中,通常是主应用程序类的包(或子包),该类的注释为@SpringBootApplication
或@EnableAutoConfiguration
.
对于许多应用程序,您所需要做的就是在类路径上放置正确的 Spring Data 依赖项。
有一个spring-boot-starter-data-jpa
对于 JPA,spring-boot-starter-data-mongodb
用于 Mongodb,以及支持技术的其他各种Starters。
首先,请创建一些存储库接口来处理@Entity
对象。
Spring Boot 确定您的Repository
通过扫描自动配置包来实现。
要获得更多控制,请使用@Enable…Repositories
来自 Spring Data 的注释。
有关 Spring Data 的更多信息,请参阅 Spring Data 项目页面。
将@Entity定义与 Spring 配置分开
Spring Boot 确定您的@Entity
通过扫描自动配置包来定义。
要获得更多控制,请使用@EntityScan
注释,如以下示例所示:
-
Java
-
Kotlin
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EntityScan(basePackageClasses = City.class)
public class MyApplication {
// ...
}
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EntityScan(basePackageClasses = [City::class])
class MyApplication {
// ...
}
筛选扫描的@Entity定义
可以过滤@Entity
使用ManagedClassNameFilter
豆。
当仅考虑可用实体的子集时,这在测试中很有用。
在以下示例中,只有来自com.example.app.customer
套餐包括:
-
Java
-
Kotlin
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.persistenceunit.ManagedClassNameFilter;
@Configuration(proxyBeanMethods = false)
public class MyEntityScanConfiguration {
@Bean
public ManagedClassNameFilter entityScanFilter() {
return (className) -> className.startsWith("com.example.app.customer.");
}
}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.orm.jpa.persistenceunit.ManagedClassNameFilter
@Configuration(proxyBeanMethods = false)
class MyEntityScanConfiguration {
@Bean
fun entityScanFilter() : ManagedClassNameFilter {
return ManagedClassNameFilter { className ->
className.startsWith("com.example.app.customer.")
}
}
}
配置 JPA 属性
Spring Data JPA 已经提供了一些独立于提供商的配置选项(例如用于 SQL 日志记录的选项),并且 Spring Boot 将这些选项以及 Hibernate 的更多选项公开为外部配置属性。 其中一些是根据上下文自动检测的,因此您不必设置它们。
这spring.jpa.hibernate.ddl-auto
是一种特殊情况,因为根据运行时条件,它具有不同的默认值。
如果使用嵌入式数据库,并且没有模式管理器(例如 Liquibase 或 Flyway)处理DataSource
,则默认为create-drop
.
在所有其他情况下,它默认为none
.
JPA 提供程序检测到要使用的方言。
如果您更喜欢自己设置方言,请将spring.jpa.database-platform
财产。
以下示例显示了最常见的设置选项:
-
Properties
-
YAML
spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
spring.jpa.show-sql=true
spring:
jpa:
hibernate:
naming:
physical-strategy: "com.example.MyPhysicalNamingStrategy"
show-sql: true
此外,中的所有属性spring.jpa.properties.*
当本地EntityManagerFactory
被创建。
您需要确保在 例如,如果要配置 Hibernate 的批量大小,则必须使用 |
如果您需要对 Hibernate 属性应用高级自定义,请考虑注册一个HibernatePropertiesCustomizer bean,该 bean 将在创建EntityManagerFactory . 这优先于自动配置应用的任何内容。 |
配置 Hibernate 命名策略
Hibernate 使用两种不同的命名策略将对象模型中的名称映射到相应的数据库名称。物理和隐式策略实现的完全限定类名可以通过设置spring.jpa.hibernate.naming.physical-strategy
和spring.jpa.hibernate.naming.implicit-strategy
属性。或者,如果ImplicitNamingStrategy
或PhysicalNamingStrategy
bean 在应用程序上下文中可用,Hibernate 将自动配置为使用它们。
默认情况下,Spring Boot 使用CamelCaseToUnderscoresNamingStrategy
.
使用此策略,所有点都替换为下划线,驼峰大小写也替换为下划线。
此外,默认情况下,所有表名都以小写形式生成。
例如,一个TelephoneNumber
实体映射到telephone_number
桌子。
如果您的架构需要混合大小写标识符,请定义自定义CamelCaseToUnderscoresNamingStrategy
bean,如以下示例所示:
-
Java
-
Kotlin
import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyHibernateConfiguration {
@Bean
public CamelCaseToUnderscoresNamingStrategy caseSensitivePhysicalNamingStrategy() {
return new CamelCaseToUnderscoresNamingStrategy() {
@Override
protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
return false;
}
};
}
}
import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyHibernateConfiguration {
@Bean
fun caseSensitivePhysicalNamingStrategy(): CamelCaseToUnderscoresNamingStrategy {
return object : CamelCaseToUnderscoresNamingStrategy() {
override fun isCaseInsensitive(jdbcEnvironment: JdbcEnvironment): Boolean {
return false
}
}
}
}
如果您更喜欢使用 Hibernate 的默认值,请设置以下属性:
-
Properties
-
YAML
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
或者,您可以配置以下 bean:
-
Java
-
Kotlin
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
class MyHibernateConfiguration {
@Bean
PhysicalNamingStrategyStandardImpl caseSensitivePhysicalNamingStrategy() {
return new PhysicalNamingStrategyStandardImpl();
}
}
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
internal class MyHibernateConfiguration {
@Bean
fun caseSensitivePhysicalNamingStrategy(): PhysicalNamingStrategyStandardImpl {
return PhysicalNamingStrategyStandardImpl()
}
}
配置休眠二级缓存
可以为一系列缓存提供程序配置 Hibernate 二级缓存。 与其将 Hibernate 配置为再次查找缓存提供者,不如尽可能提供上下文中可用的缓存提供者。
要使用 JCache 执行此作,请首先确保org.hibernate.orm:hibernate-jcache
在类路径上可用。
然后,添加一个HibernatePropertiesCustomizer
bean,如以下示例所示:
-
Java
-
Kotlin
import org.hibernate.cache.jcache.ConfigSettings;
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyHibernateSecondLevelCacheConfiguration {
@Bean
public HibernatePropertiesCustomizer hibernateSecondLevelCacheCustomizer(JCacheCacheManager cacheManager) {
return (properties) -> properties.put(ConfigSettings.CACHE_MANAGER, cacheManager.getCacheManager());
}
}
import org.hibernate.cache.jcache.ConfigSettings
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer
import org.springframework.cache.jcache.JCacheCacheManager
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyHibernateSecondLevelCacheConfiguration {
@Bean
fun hibernateSecondLevelCacheCustomizer(cacheManager: JCacheCacheManager): HibernatePropertiesCustomizer {
return HibernatePropertiesCustomizer { properties ->
properties[ConfigSettings.CACHE_MANAGER] = cacheManager.cacheManager
}
}
}
此定制器将配置 Hibernate 以使用相同的CacheManager
作为应用程序使用的。
也可以单独使用CacheManager
实例。
有关详细信息,请参阅 Hibernate 用户指南。
在 Hibernate 组件中使用依赖注入
默认情况下,Spring Boot 注册一个BeanContainer
使用BeanFactory
以便转换器和实体侦听器可以使用定期依赖注入。
您可以通过注册HibernatePropertiesCustomizer
删除或更改hibernate.resource.beans.container
财产。
使用自定义 EntityManagerFactory
要完全控制EntityManagerFactory
,您需要添加一个@Bean
名为“entityManagerFactory”。
Spring Boot 自动配置在存在该类型的 bean 时关闭其实体管理器。
当您为LocalContainerEntityManagerFactoryBean 您自己,在创建自动配置期间应用的任何自定义LocalContainerEntityManagerFactoryBean 丢失了。
确保使用自动配置的EntityManagerFactoryBuilder 以保留 JPA 和提供商属性。
如果您依赖spring.jpa.* 用于配置命名策略或 DDL 模式等内容的属性。 |
使用多个 EntityManagerFactories
如果您需要对多个数据源使用 JPA,那么您可能需要一个EntityManagerFactory
每个数据源。
这LocalContainerEntityManagerFactoryBean
from Spring ORM 允许您配置EntityManagerFactory
满足您的需求。
您还可以重复使用JpaProperties
绑定设置一秒钟EntityManagerFactory
.
基于配置第二个 DataSource
,秒EntityManagerFactory
可以定义,如以下示例所示:
-
Java
-
Kotlin
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
@Configuration(proxyBeanMethods = false)
public class MyAdditionalEntityManagerFactoryConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.jpa")
public JpaProperties secondJpaProperties() {
return new JpaProperties();
}
@Qualifier("second")
@Bean(defaultCandidate = false)
public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory(@Qualifier("second") DataSource dataSource,
@Qualifier("second") JpaProperties jpaProperties) {
EntityManagerFactoryBuilder builder = createEntityManagerFactoryBuilder(jpaProperties);
return builder.dataSource(dataSource).packages(Order.class).persistenceUnit("second").build();
}
private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties jpaProperties) {
JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(jpaProperties);
Function<DataSource, Map<String, ?>> jpaPropertiesFactory = (dataSource) -> createJpaProperties(dataSource,
jpaProperties.getProperties());
return new EntityManagerFactoryBuilder(jpaVendorAdapter, jpaPropertiesFactory, null);
}
private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties) {
// ... map JPA properties as needed
return new HibernateJpaVendorAdapter();
}
private Map<String, ?> createJpaProperties(DataSource dataSource, Map<String, ?> existingProperties) {
Map<String, ?> jpaProperties = new LinkedHashMap<>(existingProperties);
// ... map JPA properties that require the DataSource (e.g. DDL flags)
return jpaProperties;
}
}
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.orm.jpa.JpaVendorAdapter
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter
import javax.sql.DataSource
@Configuration(proxyBeanMethods = false)
class MyAdditionalEntityManagerFactoryConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.jpa")
fun secondJpaProperties(): JpaProperties {
return JpaProperties()
}
@Qualifier("second")
@Bean(defaultCandidate = false)
fun firstEntityManagerFactory(
@Qualifier("second") dataSource: DataSource,
@Qualifier("second") jpaProperties: JpaProperties
): LocalContainerEntityManagerFactoryBean {
val builder = createEntityManagerFactoryBuilder(jpaProperties)
return builder.dataSource(dataSource).packages(Order::class.java).persistenceUnit("second").build()
}
private fun createEntityManagerFactoryBuilder(jpaProperties: JpaProperties): EntityManagerFactoryBuilder {
val jpaVendorAdapter = createJpaVendorAdapter(jpaProperties)
val jpaPropertiesFactory = { dataSource: DataSource ->
createJpaProperties(dataSource, jpaProperties.properties) }
return EntityManagerFactoryBuilder(jpaVendorAdapter, jpaPropertiesFactory, null)
}
private fun createJpaVendorAdapter(jpaProperties: JpaProperties): JpaVendorAdapter {
// ... map JPA properties as needed
return HibernateJpaVendorAdapter()
}
private fun createJpaProperties(dataSource: DataSource, existingProperties: Map<String, *>): Map<String, *> {
val jpaProperties: Map<String, *> = LinkedHashMap(existingProperties)
// ... map JPA properties that require the DataSource (e.g. DDL flags)
return jpaProperties
}
}
上面的示例创建了一个EntityManagerFactory
使用DataSource
bean 符合@Qualifier("second")
.
它扫描位于与Order
.
可以使用app.jpa
Namespace。
使用@Bean(defaultCandidate=false)
允许secondJpaProperties
和secondEntityManagerFactory
在不干扰相同类型的自动配置 bean 的情况下定义 bean。
Spring Framework 参考文档更详细地描述了此功能。 |
您应该为需要 JPA 访问权限的任何其他数据源提供类似的配置。
要完成图片,您需要配置一个JpaTransactionManager
对于每个EntityManagerFactory
也。
或者,您可以使用跨两者的 JTA 事务管理器。
如果使用 Spring Data,则需要配置@EnableJpaRepositories
因此,如以下示例所示:
-
Java
-
Kotlin
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Order.class, entityManagerFactoryRef = "entityManagerFactory")
public class OrderConfiguration {
}
import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = [Order::class], entityManagerFactoryRef = "firstEntityManagerFactory")
class OrderConfiguration
-
Java
-
Kotlin
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Customer.class, entityManagerFactoryRef = "secondEntityManagerFactory")
public class CustomerConfiguration {
}
import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = [Customer::class], entityManagerFactoryRef = "secondEntityManagerFactory")
class CustomerConfiguration
使用传统的persistence.xml文件
Spring Boot 不会搜索或使用META-INF/persistence.xml
默认情况下。
如果您更喜欢使用传统的persistence.xml
,您需要定义自己的@Bean
类型LocalEntityManagerFactoryBean
(ID 为 'entityManagerFactory') 并在其中设置持久性单元名称。
看JpaBaseConfiguration
为默认设置。
使用 Spring Data JPA 和 Mongo 存储库
Spring Data JPA 和 Spring Data Mongo 都可以自动创建Repository
为您实现。
如果它们都存在于类路径上,则可能需要执行一些额外的配置来告诉 Spring Boot 要创建哪些存储库。
最明确的方法是使用标准的 Spring Data@EnableJpaRepositories
和@EnableMongoRepositories
注释并提供您的位置Repository
接口。
还有标志(spring.data.*.repositories.enabled
和spring.data.*.repositories.type
),可用于在外部配置中打开和关闭自动配置的存储库。
这样做很有用,例如,如果您想关闭 Mongo 存储库并仍然使用自动配置的MongoTemplate
.
其他自动配置的 Spring Data 存储库类型(Elasticsearch、Redis 等)也存在相同的障碍和相同的功能。 要使用它们,请相应地更改注释和标志的名称。
自定义 Spring Data 的 Web 支持
Spring Data 提供 Web 支持,可简化 Web 应用程序中 Spring Data 存储库的使用。
Spring Boot 在spring.data.web
命名空间,用于自定义其配置。
请注意,如果您使用的是 Spring Data REST,则必须使用spring.data.rest
命名空间。
将 Spring 数据存储库公开为 REST 端点
Spring Data REST 可以公开Repository
实现作为 REST 端点,
前提是已为应用程序启用了 Spring MVC。
Spring Boot 公开了一组有用的属性(从spring.data.rest
命名空间),自定义RepositoryRestConfiguration
.
如果需要提供额外的自定义,则应使用RepositoryRestConfigurer
豆。
如果您未在自定义中指定任何订单RepositoryRestConfigurer ,它运行在 Spring Boot 内部使用的那个之后。
如果您需要指定订单,请确保它大于 0。 |
配置 JPA 使用的组件
如果要配置 JPA 使用的组件,那么需要确保该组件在 JPA 之前初始化。 当组件自动配置时,Spring Boot 会为您处理此问题。 例如,当 Flyway 自动配置时,Hibernate 被配置为依赖于 Flyway,以便 Flyway 有机会在 Hibernate 尝试使用它之前初始化数据库。
如果您自己配置组件,则可以使用EntityManagerFactoryDependsOnPostProcessor
子类作为设置必要依赖项的便捷方式。
例如,如果您使用 Hibernate Search 和 Elasticsearch 作为其索引管理器,则任何EntityManagerFactory
bean 必须配置为依赖于elasticsearchClient
bean,如以下示例所示:
-
Java
-
Kotlin
import jakarta.persistence.EntityManagerFactory;
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor;
import org.springframework.stereotype.Component;
/**
* {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that
* {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean.
*/
@Component
public class ElasticsearchEntityManagerFactoryDependsOnPostProcessor
extends EntityManagerFactoryDependsOnPostProcessor {
public ElasticsearchEntityManagerFactoryDependsOnPostProcessor() {
super("elasticsearchClient");
}
}
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor
import org.springframework.stereotype.Component
@Component
class ElasticsearchEntityManagerFactoryDependsOnPostProcessor :
EntityManagerFactoryDependsOnPostProcessor("elasticsearchClient")
使用两个数据源配置 jOOQ
如果您需要将 jOOQ 与多个数据源一起使用,您应该创建自己的DSLContext
对于每一个。
看JooqAutoConfiguration
了解更多详情。
特别ExceptionTranslatorExecuteListener 和SpringTransactionProvider 可以重复使用,以提供与自动配置对单个DataSource . |