此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10Spring中文文档

此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Framework 6.1.10Spring中文文档

该软件包支持嵌入式 Java 数据库引擎。提供对 HSQL、H2Derby 的支持 本地。您还可以使用可扩展的 API 插入新的嵌入式数据库类型和实现。org.springframework.jdbc.datasource.embeddedDataSourceSpring中文文档

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

嵌入式数据库在项目的开发阶段非常有用,因为它 轻量级性质。优点包括易于配置、启动时间短、 可测试性,以及在开发过程中快速发展 SQL 的能力。Spring中文文档

创建嵌入式数据库

您可以将嵌入式数据库实例公开为 Bean,如以下示例所示:Spring中文文档

@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 数据库,该数据库填充了来自 类路径根目录中的 and 资源。此外,作为 最佳做法是为嵌入式数据库分配一个唯一生成的名称。这 嵌入式数据库作为 Bean 类型提供给 Spring 容器,然后可以根据需要将其注入到数据访问对象中。schema.sqltest-data.sqljavax.sql.DataSourceSpring中文文档

有关所有受支持选项的更多详细信息,请参阅 EmbeddedDatabaseBuilder 的 javadocSpring中文文档

选择嵌入式数据库类型

本节介绍如何选择 Spring 的三个嵌入式数据库之一 支持。它包括以下主题:Spring中文文档

使用 HSQL

Spring 支持 HSQL 1.8.0 及以上版本。HSQL 是默认的嵌入式数据库,如果没有类型 明确指定。若要显式指定 HSQL,请将标记的属性设置为 。如果使用构建器 API,请使用 .typeembedded-databaseHSQLsetType(EmbeddedDatabaseType)EmbeddedDatabaseType.HSQLSpring中文文档

使用 H2

Spring 支持 H2 数据库。要启用 H2,请将标签的属性设置为 。如果使用构建器 API,请使用 .typeembedded-databaseH2setType(EmbeddedDatabaseType)EmbeddedDatabaseType.H2Spring中文文档

使用 Derby

Spring 支持 Apache Derby 10.5 及更高版本。要启用 Derby,请将标记的属性设置为 。如果您使用构建器 API, 使用 调用该方法。typeembedded-databaseDERBYsetType(EmbeddedDatabaseType)EmbeddedDatabaseType.DERBYSpring中文文档

自定义嵌入式数据库类型

虽然每种支持的类型都带有默认连接设置,但这是可能的 如有必要,请自定义它们。以下示例将 H2 与自定义驱动程序配合使用:Spring中文文档

   @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 中将嵌入式数据库配置为 Bean 在创建嵌入式数据库中。 以下列表显示了测试模板:ApplicationContextSpring中文文档

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 配置文件或类负责,则很容易发生 用于创建嵌入式数据库,然后重用相应的配置 跨同一测试套件(即在同一 JVM 中)中的多个测试场景 process) — 例如,针对嵌入式数据库的集成测试,其配置仅在 Bean 定义方面有所不同 配置文件处于活动状态。@ConfigurationApplicationContextSpring中文文档

此类错误的根本原因是 Spring 的 (使用 在内部,由 XML 命名空间元素和 for Java 配置)将嵌入式数据库的名称设置为(如果未另行指定)。对于 的情况, 嵌入式数据库通常被分配一个与 Bean 的名称相等的名称(通常, 像这样的东西)。因此,随后尝试创建嵌入式数据库 不会生成新数据库。相反,将重用相同的 JDBC 连接 URL, 并且尝试创建新的嵌入式数据库实际上指向现有的 从相同的配置创建的嵌入式数据库。EmbeddedDatabaseFactory<jdbc:embedded-database>EmbeddedDatabaseBuildertestdb<jdbc:embedded-database>iddataSourceSpring中文文档

为了解决这个常见问题,Spring Framework 4.2 支持生成 嵌入式数据库的唯一名称。若要启用生成的名称,请使用以下名称之一 以下选项。Spring中文文档

扩展嵌入式数据库支持

您可以通过两种方式扩展 Spring JDBC 嵌入式数据库支持:Spring中文文档

  • 实现以支持新的嵌入式数据库类型。EmbeddedDatabaseConfigurerSpring中文文档

  • 实现以支持新的实现,例如 用于管理嵌入式数据库连接的连接池。DataSourceFactoryDataSourceSpring中文文档

我们鼓励您在 GitHub Issues 上为 Spring 社区贡献扩展。Spring中文文档