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

嵌入式数据库支持

org.springframework.jdbc.datasource.embeddedpackage 提供对嵌入式的支持 Java 数据库引擎。提供对 HSQLH2Derby 的支持 本地。您还可以使用可扩展的 API 来插入新的嵌入式数据库类型,并DataSource实现。spring-doc.cadn.net.cn

为什么要使用嵌入式数据库?

嵌入式数据库在项目的开发阶段很有用,因为它 轻质性质。优点包括易于配置、快速启动时间、 可测试性,以及在开发过程中快速发展 SQL 的能力。spring-doc.cadn.net.cn

使用 Spring XML 创建嵌入式数据库

如果要将嵌入式数据库实例公开为 Spring 中的 beanApplicationContext,您可以使用embedded-database标记中的spring-jdbcNamespace:spring-doc.cadn.net.cn

<jdbc:embedded-database id="dataSource" generate-name="true">
	<jdbc:script location="classpath:schema.sql"/>
	<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>

上述配置创建一个嵌入式 HSQL 数据库,该数据库填充了来自 这schema.sqltest-data.sql类路径根目录中的资源。此外,作为 最佳做法是为嵌入式数据库分配一个唯一生成的名称。这 嵌入式数据库作为类型javax.sql.DataSource然后可以根据需要将其注入到数据访问对象中。spring-doc.cadn.net.cn

以编程方式创建嵌入式数据库

EmbeddedDatabaseBuilderclass 提供了一个流畅的 API,用于构建嵌入式 数据库。当您需要在 独立环境或独立集成测试,如以下示例所示:spring-doc.cadn.net.cn

EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
		.generateUniqueName(true)
		.setType(H2)
		.setScriptEncoding("UTF-8")
		.ignoreFailedDrops(true)
		.addScript("schema.sql")
		.addScripts("user_data.sql", "country_data.sql")
		.build();

// perform actions against the db (EmbeddedDatabase extends javax.sql.DataSource)

db.shutdown()
val db = EmbeddedDatabaseBuilder()
		.generateUniqueName(true)
		.setType(H2)
		.setScriptEncoding("UTF-8")
		.ignoreFailedDrops(true)
		.addScript("schema.sql")
		.addScripts("user_data.sql", "country_data.sql")
		.build()

// perform actions against the db (EmbeddedDatabase extends javax.sql.DataSource)

db.shutdown()

请参阅javadoc 的EmbeddedDatabaseBuilder有关所有支持选项的更多详细信息。spring-doc.cadn.net.cn

您还可以使用EmbeddedDatabaseBuilder使用 Java 创建嵌入式数据库 配置,如以下示例所示:spring-doc.cadn.net.cn

@Configuration
public class DataSourceConfig {

	@Bean
	public DataSource dataSource() {
		return new EmbeddedDatabaseBuilder()
				.generateUniqueName(true)
				.setType(H2)
				.setScriptEncoding("UTF-8")
				.ignoreFailedDrops(true)
				.addScript("schema.sql")
				.addScripts("user_data.sql", "country_data.sql")
				.build();
	}
}
@Configuration
class DataSourceConfig {

	@Bean
	fun dataSource(): DataSource {
		return EmbeddedDatabaseBuilder()
				.generateUniqueName(true)
				.setType(H2)
				.setScriptEncoding("UTF-8")
				.ignoreFailedDrops(true)
				.addScript("schema.sql")
				.addScripts("user_data.sql", "country_data.sql")
				.build()
	}
}

选择嵌入式数据库类型

本节介绍如何选择 Spring 的三个嵌入式数据库之一 支持。它包括以下主题:spring-doc.cadn.net.cn

使用 HSQL

Spring 支持 HSQL 1.8.0 及更高版本。如果没有类型 显式指定。要显式指定 HSQL,请将type属性的embedded-database标签设置为HSQL.如果您使用构建器 API,请调用setType(EmbeddedDatabaseType)方法EmbeddedDatabaseType.HSQL.spring-doc.cadn.net.cn

使用 H2

Spring 支持 H2 数据库。要启用 H2,请将type属性的embedded-database标签设置为H2.如果您使用构建器 API,请调用setType(EmbeddedDatabaseType)方法EmbeddedDatabaseType.H2.spring-doc.cadn.net.cn

使用 Derby

Spring 支持 Apache Derby 10.5 及更高版本。要启用 Derby,请将type属性的embedded-database标签设置为DERBY.如果您使用构建器 API, 调用setType(EmbeddedDatabaseType)方法EmbeddedDatabaseType.DERBY.spring-doc.cadn.net.cn

使用嵌入式数据库测试数据访问逻辑

嵌入式数据库提供了一种轻量级的方法来测试数据访问代码。下一个示例是 使用嵌入式数据库的数据访问集成测试模板。使用这样的模板 当嵌入式数据库不需要在测试中重用时,对于一次性可能很有用 类。但是,如果您希望创建在测试套件中共享的嵌入式数据库, 考虑使用 Spring TestContext 框架和 在 Spring 中将嵌入式数据库配置为 beanApplicationContext如所述 使用 Spring XML 创建嵌入式数据库和以编程方式创建嵌入式数据库。以下列表 显示测试模板:spring-doc.cadn.net.cn

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阶级负责 用于创建嵌入式数据库,然后重复使用相应的配置 跨同一测试套件中的多个测试场景(即在同一 JVM 中) process) — 例如,针对嵌入式数据库的集成测试,其ApplicationContext配置仅与哪个 Bean 定义不同 配置文件处于活动状态。spring-doc.cadn.net.cn

此类错误的根本原因是 Spring 的EmbeddedDatabaseFactory(用过 在内部由<jdbc:embedded-database>XML 命名空间元素和EmbeddedDatabaseBuilder对于 Java 配置)将嵌入式数据库的名称设置为testdb如无特别说明。对于以下情况<jdbc:embedded-database>这 嵌入式数据库通常被分配一个与 bean 的id(通常, 类似dataSource).因此,后续尝试创建嵌入式数据库 不会导致新数据库。相反,将重复使用相同的 JDBC 连接 URL, 并且尝试创建新的嵌入式数据库实际上指向现有的 从相同配置创建的嵌入式数据库。spring-doc.cadn.net.cn

为了解决这个常见问题,Spring Framework 4.2 提供了对生成 嵌入式数据库的唯一名称。要启用生成的名称,请使用 以下选项。spring-doc.cadn.net.cn

扩展嵌入式数据库支持

您可以通过两种方式扩展 Spring JDBC 嵌入式数据库支持:spring-doc.cadn.net.cn

  • 实现EmbeddedDatabaseConfigurer以支持新的嵌入式数据库类型。spring-doc.cadn.net.cn

  • 实现DataSourceFactory以支持新的DataSource实现,例如 连接池来管理嵌入式数据库连接。spring-doc.cadn.net.cn

我们鼓励你在 GitHub Issues 上向 Spring 社区贡献扩展。spring-doc.cadn.net.cn