对于最新的稳定版本,请使用 Spring Boot 3.4.0spring-doc.cadn.net.cn

数据访问

Spring Boot 包含许多用于处理数据源的 Starter。 本节回答与执行此作相关的问题。spring-doc.cadn.net.cn

配置自定义数据源

配置您自己的DataSource中,定义一个@Bean的配置中。 Spring Boot 重用了DataSource任何需要的地方,包括数据库初始化。 如果需要外部化一些设置,可以将DataSource添加到环境中(请参阅 第三方配置)。spring-doc.cadn.net.cn

以下示例显示了如何在 Bean 中定义数据源:spring-doc.cadn.net.cn

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()
	}

}

以下示例显示如何通过设置数据源的属性来定义数据源:spring-doc.cadn.net.cn

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-doc.cadn.net.cn

Spring Boot 还提供了一个名为DataSourceBuilder,该数据源可用于创建标准数据源之一(如果它在 Classpath 上)。 构建器可以根据 Classpath 上可用的内容来检测要使用的 Classpath。 它还会根据 JDBC URL 自动检测驱动程序。spring-doc.cadn.net.cn

以下示例演示如何使用DataSourceBuilder:spring-doc.cadn.net.cn

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,您只需要连接信息。 还可以提供特定于池的设置。 检查将在运行时使用的实现以获取更多详细信息。spring-doc.cadn.net.cn

以下示例演示如何通过设置属性来定义 JDBC 数据源:spring-doc.cadn.net.cn

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

但是,由于该方法的DataSourcereturn 类型。 这将隐藏连接池的实际类型,因此不会为您的自定义生成配置属性元数据DataSource并且您的 IDE 中没有可用的自动完成功能。 要解决此问题,请使用 builder 的type(Class)方法指定DataSource以构建并更新方法的返回类型。 例如,下面显示了如何创建一个HikariDataSourceDataSourceBuilder:spring-doc.cadn.net.cn

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属性,这意味着您必须按如下方式重写配置:spring-doc.cadn.net.cn

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它将处理urljdbc-url为您翻译。 您可以初始化DataSourceBuilder从任何DataSourceProperties对象使用其initializeDataSourceBuilder()方法。 你可以注入DataSourceProperties但是,Spring Boot 会自动创建,这会将您的配置拆分为spring.datasource.*app.datasource.*. 为避免这种情况,请定义一个自定义DataSourceProperties替换为自定义配置 properties 前缀,如以下示例所示:spring-doc.cadn.net.cn

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负责urljdbc-urltranslation,因此您可以按如下方式对其进行配置:spring-doc.cadn.net.cn

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将不起作用。spring-doc.cadn.net.cn

支持的连接池中所述,DataSourceBuilder支持多个不同的连接池。 要使用 Hikari 以外的池,请将其添加到 Classpath 中,使用type(Class)方法指定要使用的 pool 类,并更新@Beanmethod 的 return 类型进行匹配。 这还将为您提供所选特定连接池的配置属性元数据。spring-doc.cadn.net.cn

Spring Boot 会将 Hikari 特定的设置暴露给spring.datasource.hikari. 此示例使用更通用的configurationsub 命名空间为例,不支持多个 DataSource 实现。

配置两个数据源

如果需要配置多个数据源,则可以应用上一节中描述的相同技巧。 但是,您必须标记DataSource实例设置为@Primary,因为未来的各种 auto-configuration 都希望能够按类型获得一个。spring-doc.cadn.net.cn

如果您创建自己的DataSource时,自动配置将回退。 在以下示例中,我们提供的功能集与自动配置在主数据源上提供的功能集完全相同spring-doc.cadn.net.cn

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)。

这两个数据源也都绑定用于高级自定义。 例如,您可以按如下方式配置它们:spring-doc.cadn.net.cn

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以及,如以下示例所示:spring-doc.cadn.net.cn

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 在自动配置中使用的逻辑相同。 请注意,每个configurationSub 命名空间 根据所选实现提供高级设置。spring-doc.cadn.net.cn

配置单个自定义 DataSource中,一个或两个DataSource可以使用type(Class)method 开启DataSourceBuilder. 有关支持的类型的详细信息,请参阅支持的连接池spring-doc.cadn.net.cn

使用 Spring 数据存储库

Spring Data 可以创建Repository各种风格的接口。 Spring Boot 会为您处理所有这些作,只要这些Repository实现包含在一个自动配置包中,通常是主应用程序类的包(或子包),该包带有@SpringBootApplication@EnableAutoConfiguration.spring-doc.cadn.net.cn

对于许多应用程序,您所需要做的就是将正确的 Spring Data 依赖项放在 Classpath 上。 有一个spring-boot-starter-data-jpa对于 JPA,spring-boot-starter-data-mongodb适用于 MongoDB,以及支持技术的各种其他Starters。 首先,创建一些存储库接口来处理@Entity对象。spring-doc.cadn.net.cn

Spring Boot 确定Repository实施。 如需更多控制,请使用@Enable…Repositories来自 Spring Data 的注释。spring-doc.cadn.net.cn

有关 Spring Data 的更多信息,请参阅 Spring Data 项目页面spring-doc.cadn.net.cn

将 @Entity 定义与 Spring 配置分开

Spring Boot 确定@Entitydefinitions 来扫描 auto-configuration 软件包。 如需更多控制,请使用@EntityScanannotation 中,如以下示例所示:spring-doc.cadn.net.cn

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套餐包括:spring-doc.cadn.net.cn

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-doc.cadn.net.cn

spring.jpa.hibernate.ddl-auto是一种特殊情况,因为根据运行时条件,它具有不同的默认值。 如果使用嵌入式数据库,并且没有架构管理器(例如 Liquibase 或 Flyway)正在处理DataSource,则默认为create-drop. 在所有其他情况下,它默认为none.spring-doc.cadn.net.cn

要使用的方言由 JPA 提供程序检测。 如果您更喜欢自己设置方言,请将spring.jpa.database-platform财产。spring-doc.cadn.net.cn

以下示例显示了要设置的最常见选项:spring-doc.cadn.net.cn

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已创建。spring-doc.cadn.net.cn

您需要确保在spring.jpa.properties.*与您的 JPA 提供商所期望的完全匹配。 Spring Boot 不会尝试对这些条目进行任何类型的松散绑定。spring-doc.cadn.net.cn

例如,如果要配置 Hibernate 的批处理大小,则必须使用spring.jpa.properties.hibernate.jdbc.batch_size. 如果您使用其他表单,例如batchSizebatch-size,则 Hibernate 不会应用该设置。spring-doc.cadn.net.cn

如果需要对 Hibernate 属性应用高级自定义,请考虑注册一个HibernatePropertiesCustomizerbean 的 bean 中,将在创建EntityManagerFactory. 这优先于自动配置应用的任何内容。

配置 Hibernate 命名策略

Hibernate 使用两种不同的命名策略将名称从对象模型映射到相应的数据库名称。 物理和隐式策略实现的完全限定类名可以通过设置spring.jpa.hibernate.naming.physical-strategyspring.jpa.hibernate.naming.implicit-strategy属性。 或者,如果ImplicitNamingStrategyPhysicalNamingStrategybean 在应用程序上下文中可用,Hibernate 将自动配置为使用它们。spring-doc.cadn.net.cn

默认情况下, Spring Boot 使用CamelCaseToUnderscoresNamingStrategy. 使用此策略,所有点都替换为下划线,驼峰大小写也替换为下划线。 此外,默认情况下,所有表名都以小写形式生成。 例如,TelephoneNumber实体映射到telephone_number桌子。 如果您的架构需要大小写混合的标识符,请定义自定义CamelCaseToUnderscoresNamingStrategybean,如以下示例所示:spring-doc.cadn.net.cn

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 的默认值,请设置以下属性:spring-doc.cadn.net.cn

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:spring-doc.cadn.net.cn

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 再次查找缓存提供程序,不如尽可能提供上下文中可用的缓存提供程序。spring-doc.cadn.net.cn

要使用 JCache 执行此作,首先确保org.hibernate.orm:hibernate-jcache在 Classpath 上可用。 然后,添加一个HibernatePropertiesCustomizerbean,如以下示例所示:spring-doc.cadn.net.cn

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 用户指南spring-doc.cadn.net.cn

在 Hibernate 组件中使用依赖注入

默认情况下, Spring Boot 会注册一个BeanContainer使用BeanFactory以便转换器和实体侦听器可以使用常规依赖项注入。spring-doc.cadn.net.cn

您可以通过注册HibernatePropertiesCustomizer,用于删除或更改hibernate.resource.beans.container财产。spring-doc.cadn.net.cn

使用自定义 EntityManagerFactory

要完全控制EntityManagerFactory,您需要添加一个@Bean命名为 'entityManagerFactory'。 Spring Boot 自动配置在存在该类型的 bean 时关闭其实体 manager。spring-doc.cadn.net.cn

使用多个 EntityManagerFactories

如果您需要对多个数据源使用 JPA,则可能需要一个数据源EntityManagerFactory每个数据源。 这LocalContainerEntityManagerFactoryBean来自 Spring ORM 允许您配置EntityManagerFactory满足您的需求。 您还可以重复使用JpaProperties以绑定每个EntityManagerFactory,如以下示例所示:spring-doc.cadn.net.cn

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.jpaNamespace。spring-doc.cadn.net.cn

当你为LocalContainerEntityManagerFactoryBean您自己,以及在创建自动配置的LocalContainerEntityManagerFactoryBean丢失了。 例如,在 Hibernate 的情况下,任何spring.jpa.hibernate前缀不会自动应用于您的LocalContainerEntityManagerFactoryBean. 如果您依赖这些属性来配置命名策略或 DDL 模式等内容,则需要在创建LocalContainerEntityManagerFactoryBean豆。

您应该为需要 JPA 访问权限的任何其他数据源提供类似的配置。 要完成图片,您需要配置JpaTransactionManager对于每个EntityManagerFactory也。 或者,您可以使用跨越两者的 JTA 事务 Management 器。spring-doc.cadn.net.cn

如果使用 Spring Data,则需要配置@EnableJpaRepositories因此,如以下示例所示:spring-doc.cadn.net.cn

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
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')并在此处设置持久化单元名称。spring-doc.cadn.net.cn

使用 Spring Data JPA 和 Mongo 存储库

Spring Data JPA 和 Spring Data Mongo 都可以自动创建Repository实现。 如果它们都存在于 Classpath 中,则可能必须进行一些额外的配置以告诉 Spring Boot 要创建哪些存储库。 最明确的方法是使用标准的 Spring Data@EnableJpaRepositories@EnableMongoRepositoriesannotations 并提供Repository接口。spring-doc.cadn.net.cn

还有一些标志 (spring.data.*.repositories.enabledspring.data.*.repositories.type),您可以使用该存储库在外部配置中打开和关闭自动配置的存储库。 这样做很有用,例如,如果您想关闭 Mongo 存储库并仍然使用自动配置的MongoTemplate.spring-doc.cadn.net.cn

其他自动配置的 Spring Data 存储库类型(Elasticsearch、Redis 等)存在相同的障碍和相同的功能。 要使用它们,请相应地更改注释和标志的名称。spring-doc.cadn.net.cn

自定义 Spring Data 的 Web 支持

Spring Data 提供 Web 支持,可简化 Spring Data 存储库在 Web 应用程序中的使用。 Spring Boot 在spring.data.webnamespace 来自定义其配置。 请注意,如果您使用的是 Spring Data REST,则必须使用spring.data.rest命名空间。spring-doc.cadn.net.cn

将 Spring Data Repositories 公开为 REST 端点

Spring Data REST 可以公开Repository实现作为 REST 端点, 前提是已为应用程序启用了 Spring MVC。spring-doc.cadn.net.cn

Spring Boot 公开了一组有用的属性(从spring.data.rest命名空间),自定义RepositoryRestConfiguration. 如果您需要提供额外的自定义,则应使用RepositoryRestConfigurer豆。spring-doc.cadn.net.cn

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

配置 JPA 使用的组件

如果要配置 JPA 使用的组件,则需要确保在 JPA 之前初始化该组件。 当组件被自动配置时, Spring Boot 会为你处理这个问题。 例如,当 Flyway 被自动配置时,Hibernate 被配置为依赖于 Flyway,以便 Flyway 有机会在 Hibernate 尝试使用数据库之前初始化数据库。spring-doc.cadn.net.cn

如果您自己配置组件,则可以使用EntityManagerFactoryDependsOnPostProcessorsubclass 作为设置必要依赖项的便捷方式。 例如,如果您使用 Hibernate Search 并将 Elasticsearch 作为其索引管理器,则任何EntityManagerFactorybean 必须配置为依赖于elasticsearchClientbean,如以下示例所示:spring-doc.cadn.net.cn

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了解更多详情。spring-doc.cadn.net.cn

特别JooqExceptionTranslatorSpringTransactionProvider可以重复使用以提供与自动配置对单个DataSource.