对于最新的稳定版本,请使用 Spring Boot 3.4.0! |
数据访问
Spring Boot 包含许多用于处理数据源的 Starter。 本节回答与执行此作相关的问题。
配置自定义数据源
配置您自己的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
,该数据源可用于创建标准数据源之一(如果它在 Classpath 上)。
构建器可以根据 Classpath 上可用的内容来检测要使用的 Classpath。
它还会根据 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
return 类型。
这将隐藏连接池的实际类型,因此不会为您的自定义生成配置属性元数据DataSource
并且您的 IDE 中没有可用的自动完成功能。
要解决此问题,请使用 builder 的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
替换为自定义配置 properties 前缀,如以下示例所示:
-
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 以外的池,请将其添加到 Classpath 中,使用type(Class)
方法指定要使用的 pool 类,并更新@Bean
method 的 return 类型进行匹配。
这还将为您提供所选特定连接池的配置属性元数据。
Spring Boot 会将 Hikari 特定的设置暴露给spring.datasource.hikari .
此示例使用更通用的configuration sub 命名空间为例,不支持多个 DataSource 实现。 |
请参阅配置 DataSource 和DataSourceAutoConfiguration
类了解更多详情。
配置两个数据源
如果需要配置多个数据源,则可以应用上一节中描述的相同技巧。
但是,您必须标记DataSource
实例设置为@Primary
,因为未来的各种 auto-configuration 都希望能够按类型获得一个。
如果您创建自己的DataSource
时,自动配置将回退。
在以下示例中,我们提供的功能集与自动配置在主数据源上提供的功能集完全相同:
-
Java
-
Kotlin
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
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;
import org.springframework.context.annotation.Primary;
@Configuration(proxyBeanMethods = false)
public class MyDataSourcesConfiguration {
@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("app.datasource.first.configuration")
public HikariDataSource firstDataSource(DataSourceProperties firstDataSourceProperties) {
return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
@Bean
@ConfigurationProperties("app.datasource.second")
public HikariDataSource secondDataSource() {
return DataSourceBuilder.create().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.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary
@Configuration(proxyBeanMethods = false)
class MyDataSourcesConfiguration {
@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
fun firstDataSourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Bean
@Primary
@ConfigurationProperties("app.datasource.first.configuration")
fun firstDataSource(firstDataSourceProperties: DataSourceProperties): HikariDataSource {
return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
}
@Bean
@ConfigurationProperties("app.datasource.second")
fun secondDataSource(): HikariDataSource {
return DataSourceBuilder.create().type(HikariDataSource::class.java).build()
}
}
firstDataSourceProperties 必须标记为@Primary ,以便 Database Initializer 功能使用您的副本(如果使用 Initializer)。 |
这两个数据源也都绑定用于高级自定义。 例如,您可以按如下方式配置它们:
-
Properties
-
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
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
以及,如以下示例所示:
-
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;
import org.springframework.context.annotation.Primary;
@Configuration(proxyBeanMethods = false)
public class MyCompleteDataSourcesConfiguration {
@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("app.datasource.first.configuration")
public HikariDataSource firstDataSource(DataSourceProperties firstDataSourceProperties) {
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 HikariDataSource secondDataSource(
@Qualifier("secondDataSourceProperties") DataSourceProperties secondDataSourceProperties) {
return secondDataSourceProperties.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 MyCompleteDataSourcesConfiguration {
@Bean
@Primary
@ConfigurationProperties("app.datasource.first")
fun firstDataSourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Bean
@Primary
@ConfigurationProperties("app.datasource.first.configuration")
fun firstDataSource(firstDataSourceProperties: DataSourceProperties): HikariDataSource {
return firstDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
}
@Bean
@ConfigurationProperties("app.datasource.second")
fun secondDataSourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Bean
@ConfigurationProperties("app.datasource.second.configuration")
fun secondDataSource(secondDataSourceProperties: DataSourceProperties): HikariDataSource {
return secondDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
}
}
前面的示例在自定义配置属性命名空间上配置两个数据源,其逻辑与 Spring Boot 在自动配置中使用的逻辑相同。
请注意,每个configuration
Sub 命名空间 根据所选实现提供高级设置。
与配置单个自定义 DataSource
中,一个或两个DataSource
可以使用type(Class)
method 开启DataSourceBuilder
.
有关支持的类型的详细信息,请参阅支持的连接池。
使用 Spring 数据存储库
Spring Data 可以创建Repository
各种风格的接口。
Spring Boot 会为您处理所有这些作,只要这些Repository
实现包含在一个自动配置包中,通常是主应用程序类的包(或子包),该包带有@SpringBootApplication
或@EnableAutoConfiguration
.
对于许多应用程序,您所需要做的就是将正确的 Spring Data 依赖项放在 Classpath 上。
有一个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
definitions 来扫描 auto-configuration 软件包。
如需更多控制,请使用@EntityScan
annotation 中,如以下示例所示:
-
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.*
作为普通的 JPA 属性(前缀被剥离)传递,当本地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 Second-Level Caching
可以为一系列缓存提供程序配置 Hibernate 二级缓存。 与其配置 Hibernate 再次查找缓存提供程序,不如尽可能提供上下文中可用的缓存提供程序。
要使用 JCache 执行此作,首先确保org.hibernate.orm:hibernate-jcache
在 Classpath 上可用。
然后,添加一个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
作为应用程序使用的 VPN。
也可以使用单独的CacheManager
实例。
有关详细信息,请参阅 Hibernate 用户指南。
在 Hibernate 组件中使用依赖注入
默认情况下, Spring Boot 会注册一个BeanContainer
使用BeanFactory
以便转换器和实体侦听器可以使用常规依赖项注入。
您可以通过注册HibernatePropertiesCustomizer
,用于删除或更改hibernate.resource.beans.container
财产。
使用自定义 EntityManagerFactory
要完全控制EntityManagerFactory
,您需要添加一个@Bean
命名为 'entityManagerFactory'。
Spring Boot 自动配置在存在该类型的 bean 时关闭其实体 manager。
使用多个 EntityManagerFactories
如果您需要对多个数据源使用 JPA,则可能需要一个数据源EntityManagerFactory
每个数据源。
这LocalContainerEntityManagerFactoryBean
来自 Spring ORM 允许您配置EntityManagerFactory
满足您的需求。
您还可以重复使用JpaProperties
以绑定每个EntityManagerFactory
,如以下示例所示:
-
Java
-
Kotlin
import javax.sql.DataSource;
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 MyEntityManagerFactoryConfiguration {
@Bean
@ConfigurationProperties("app.jpa.first")
public JpaProperties firstJpaProperties() {
return new JpaProperties();
}
@Bean
public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory(DataSource firstDataSource,
JpaProperties firstJpaProperties) {
EntityManagerFactoryBuilder builder = createEntityManagerFactoryBuilder(firstJpaProperties);
return builder.dataSource(firstDataSource).packages(Order.class).persistenceUnit("firstDs").build();
}
private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties jpaProperties) {
JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(jpaProperties);
return new EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.getProperties(), null);
}
private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties) {
// ... map JPA properties as needed
return new HibernateJpaVendorAdapter();
}
}
import javax.sql.DataSource
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)
class MyEntityManagerFactoryConfiguration {
@Bean
@ConfigurationProperties("app.jpa.first")
fun firstJpaProperties(): JpaProperties {
return JpaProperties()
}
@Bean
fun firstEntityManagerFactory(
firstDataSource: DataSource?,
firstJpaProperties: JpaProperties
): LocalContainerEntityManagerFactoryBean {
val builder = createEntityManagerFactoryBuilder(firstJpaProperties)
return builder.dataSource(firstDataSource).packages(Order::class.java).persistenceUnit("firstDs").build()
}
private fun createEntityManagerFactoryBuilder(jpaProperties: JpaProperties): EntityManagerFactoryBuilder {
val jpaVendorAdapter = createJpaVendorAdapter(jpaProperties)
return EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.properties, null)
}
private fun createJpaVendorAdapter(jpaProperties: JpaProperties): JpaVendorAdapter {
// ... map JPA properties as needed
return HibernateJpaVendorAdapter()
}
}
上面的示例创建了一个EntityManagerFactory
使用DataSource
名为firstDataSource
.
它扫描位于同一包中的 entity asOrder
.
可以使用app.first.jpa
Namespace。
当你为LocalContainerEntityManagerFactoryBean 您自己,以及在创建自动配置的LocalContainerEntityManagerFactoryBean 丢失了。
例如,在 Hibernate 的情况下,任何spring.jpa.hibernate 前缀不会自动应用于您的LocalContainerEntityManagerFactoryBean .
如果您依赖这些属性来配置命名策略或 DDL 模式等内容,则需要在创建LocalContainerEntityManagerFactoryBean 豆。 |
您应该为需要 JPA 访问权限的任何其他数据源提供类似的配置。
要完成图片,您需要配置JpaTransactionManager
对于每个EntityManagerFactory
也。
或者,您可以使用跨越两者的 JTA 事务 Management 器。
如果使用 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 = "firstEntityManagerFactory")
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
实现。
如果它们都存在于 Classpath 中,则可能必须进行一些额外的配置以告诉 Spring Boot 要创建哪些存储库。
最明确的方法是使用标准的 Spring Data@EnableJpaRepositories
和@EnableMongoRepositories
annotations 并提供Repository
接口。
还有一些标志 (spring.data.*.repositories.enabled
和spring.data.*.repositories.type
),您可以使用该存储库在外部配置中打开和关闭自动配置的存储库。
这样做很有用,例如,如果您想关闭 Mongo 存储库并仍然使用自动配置的MongoTemplate
.
其他自动配置的 Spring Data 存储库类型(Elasticsearch、Redis 等)存在相同的障碍和相同的功能。 要使用它们,请相应地更改注释和标志的名称。
自定义 Spring Data 的 Web 支持
Spring Data 提供 Web 支持,可简化 Spring Data 存储库在 Web 应用程序中的使用。
Spring Boot 在spring.data.web
namespace 来自定义其配置。
请注意,如果您使用的是 Spring Data REST,则必须使用spring.data.rest
命名空间。
将 Spring Data Repositories 公开为 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
subclass 作为设置必要依赖项的便捷方式。
例如,如果您使用 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
对于每个 1 个。
看JooqAutoConfiguration
了解更多详情。
特别JooqExceptionTranslator 和SpringTransactionProvider 可以重复使用以提供与自动配置对单个DataSource . |