此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.2.0! |
嵌入式数据库支持
创建嵌入式数据库
您可以将嵌入式数据库实例公开为 Bean,如下例所示:
-
Java
-
Kotlin
-
Xml
@Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(EmbeddedDatabaseType.H2)
.addScripts("schema.sql", "test-data.sql")
.build();
}
@Bean
fun dataSource() = EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(EmbeddedDatabaseType.H2)
.addScripts("schema.sql", "test-data.sql")
.build()
<jdbc:embedded-database id="dataSource" generate-name="true" type="H2">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
前面的配置创建了一个嵌入式 H2 数据库,该数据库填充了 SQL
这schema.sql
和test-data.sql
resources 的 classpath 根目录中。此外,由于
最佳做法是,为 Embedded Database 分配一个唯一生成的 Name。这
嵌入式数据库作为 Spring 容器的 bean 类型为javax.sql.DataSource
然后,可以根据需要将其注入到 Data Access 对象中。
请参阅javadoc 的EmbeddedDatabaseBuilder
了解有关所有支持选项的更多详细信息。
选择嵌入式数据库类型
本节介绍如何选择 Spring 支持。它包括以下主题:
使用 HSQL
Spring 支持 HSQL 1.8.0 及更高版本。HSQL 是默认嵌入式数据库(如果 no type 为
显式指定。要显式指定 HSQL,请将type
属性的embedded-database
标签设置为HSQL
.如果您使用构建器 API,请调用setType(EmbeddedDatabaseType)
method 替换为EmbeddedDatabaseType.HSQL
.
自定义嵌入式数据库类型
虽然每种受支持的类型都带有默认连接设置,但这是可能的 以根据需要对其进行自定义。以下示例将 H2 与自定义驱动程序一起使用:
-
Java
-
Kotlin
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setDatabaseConfigurer(EmbeddedDatabaseConfigurers
.customizeConfigurer(H2, this::customize))
.addScript("schema.sql")
.build();
}
private EmbeddedDatabaseConfigurer customize(EmbeddedDatabaseConfigurer defaultConfigurer) {
return new EmbeddedDatabaseConfigurerDelegate(defaultConfigurer) {
@Override
public void configureConnectionProperties(ConnectionProperties properties, String databaseName) {
super.configureConnectionProperties(properties, databaseName);
properties.setDriverClass(CustomDriver.class);
}
};
}
}
@Configuration
class DataSourceConfig {
@Bean
fun dataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.setDatabaseConfigurer(EmbeddedDatabaseConfigurers
.customizeConfigurer(EmbeddedDatabaseType.H2) { this.customize(it) })
.addScript("schema.sql")
.build()
}
private fun customize(defaultConfigurer: EmbeddedDatabaseConfigurer): EmbeddedDatabaseConfigurer {
return object : EmbeddedDatabaseConfigurerDelegate(defaultConfigurer) {
override fun configureConnectionProperties(
properties: ConnectionProperties,
databaseName: String
) {
super.configureConnectionProperties(properties, databaseName)
properties.setDriverClass(CustomDriver::class.java)
}
}
}
}
使用嵌入式数据库测试数据访问逻辑
嵌入式数据库提供了一种测试数据访问代码的轻量级方法。下一个示例是
使用嵌入式数据库的数据访问集成测试模板。使用此类模板
当嵌入式数据库不需要在测试中重复使用时,对于一次性作可能很有用
类。但是,如果您希望创建在测试套件中共享的嵌入式数据库,
考虑使用 Spring TestContext 框架和
在 Spring 中将嵌入式数据库配置为 beanApplicationContext
如前所述
在创建嵌入式数据库中。
下面的清单显示了测试模板:
-
Java
-
Kotlin
public class DataAccessIntegrationTestTemplate {
private EmbeddedDatabase db;
@BeforeEach
public void setUp() {
// creates an HSQL in-memory database populated from default scripts
// classpath:schema.sql and classpath:data.sql
db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.addDefaultScripts()
.build();
}
@Test
public void testDataAccess() {
JdbcTemplate template = new JdbcTemplate(db);
template.query( /* ... */ );
}
@AfterEach
public void tearDown() {
db.shutdown();
}
}
class DataAccessIntegrationTestTemplate {
private lateinit var db: EmbeddedDatabase
@BeforeEach
fun setUp() {
// creates an HSQL in-memory database populated from default scripts
// classpath:schema.sql and classpath:data.sql
db = EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.addDefaultScripts()
.build()
}
@Test
fun testDataAccess() {
val template = JdbcTemplate(db)
template.query( /* ... */)
}
@AfterEach
fun tearDown() {
db.shutdown()
}
}
为嵌入式数据库生成唯一名称
如果开发团队的测试套件
无意中尝试重新创建同一数据库的其他实例。这可以
如果 XML 配置文件或@Configuration
class 负责
创建嵌入式数据库,然后重用相应的配置
跨同一测试套件(即,在同一个 JVM 中)中的多个测试场景
进程)— 例如,针对嵌入式数据库进行集成测试,这些数据库ApplicationContext
配置仅在 bean 定义方面有所不同
配置文件处于活动状态。
此类错误的根本原因是 Spring 的EmbeddedDatabaseFactory
(已使用
在内部由<jdbc:embedded-database>
XML 命名空间元素和EmbeddedDatabaseBuilder
对于 Java 配置)将嵌入式数据库的名称设置为testdb
如果没有特别说明。对于<jdbc:embedded-database>
这
Embedded Database 通常被分配一个等于 Bean 的id
(通常,
类似dataSource
).因此,后续尝试创建嵌入式数据库
不会导致新数据库。相反,相同的 JDBC 连接 URL 被重用,
并且尝试创建新的嵌入式数据库实际上指向现有的
从相同配置创建的嵌入式数据库。
为了解决这个常见问题,Spring Framework 4.2 提供了对生成 嵌入式数据库的唯一名称。要启用生成名称的使用,请使用 以下选项。
-
EmbeddedDatabaseFactory.setGenerateUniqueDatabaseName()
-
EmbeddedDatabaseBuilder.generateUniqueName()
-
<jdbc:embedded-database generate-name="true" … >
扩展嵌入式数据库支持
您可以通过两种方式扩展 Spring JDBC 嵌入式数据库支持:
-
实现
EmbeddedDatabaseConfigurer
以支持新的 Embedded 数据库类型。 -
实现
DataSourceFactory
以支持新的DataSource
实现,例如 连接池,用于管理嵌入式数据库连接。
我们鼓励您在 GitHub Issues 上为 Spring 社区贡献扩展。