最常用且推荐的方式是通过 Spring Boot 的 @DataJpaTest 自动配置 H2 内存数据库,自动创建数据源、建表并加载 SQL 脚本;也可通过 application-test.properties 自定义连接参数与初始化行为,或手动构建 DataSource 用于无 Spring 场景。

在 Java 单元测试中启动内嵌 H2 内存数据库,最常用且推荐的方式是通过 Spring Boot 的测试支持(@SpringBootTest 或 @DataJpaTest)自动配置 H2,配合 application-test.properties 或 @TestConfiguration 显式声明数据源。无需手动 new DataSource 或启动 H2 服务,Spring 会自动完成初始化和 Schema/SQL 加载。
使用 @DataJpaTest 快速启用 H2 内存库
这是轻量级、专注 JPA 层测试的推荐方式,Spring Boot 会自动:
- 配置一个内存版 H2 数据源(
jdbc:h2:mem:testdb) - 启用
spring.jpa.hibernate.ddl-auto=create-drop,每次测试后自动重建表 - 扫描
@Entity类并创建对应表结构 - 加载
schema.sql和data.sql(若存在)
示例测试类:
@DataJpaTest
class UserRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private TestRepository repository;
@Test
void should_save_and_find_user() {
User user = new User("Alice");
entityManager.persistAndFlush(user);
assertThat(repository.findById(user.getId())).isPresent();
}
}
自定义 H2 连接参数与初始化脚本
若需控制数据库名、关闭自动建表、或执行特定 SQL,可在 src/test/resources/application-test.properties 中配置:
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
spring.datasource.url=jdbc:h2:mem:mytest;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE spring.datasource.driver-class-name=org.h2.Driver spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.jpa.hibernate.ddl-auto=none spring.sql.init.mode=always spring.sql.init.schema-locations=classpath:schema-test.sql spring.sql.init.data-locations=classpath:data-test.sql
注意:DB_CLOSE_DELAY=-1 防止多个测试间连接被意外关闭;spring.sql.init.mode=always 确保每次测试前重新执行 SQL 脚本。
纯 JUnit + H2(不依赖 Spring)
如需完全脱离 Spring 容器(例如测试 DAO 工具类),可手动构建 HikariDataSource 或 DriverManagerDataSource:
@Test
void testWithPlainH2() throws SQLException {
String url = "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1";
DataSource ds = new DriverManagerDataSource(url, "sa", "");
// 手动建表(可用 ScriptRunner 或 executeUpdate)
try (Connection conn = ds.getConnection();
Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE users(id BIGINT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50))");
stmt.execute("INSERT INTO users(name) VALUES ('Bob')");
}
// 执行查询验证...
}
这种方式灵活但需自行管理生命周期和 SQL 初始化,适合极简场景或教学演示。
避免常见陷阱
以下问题在实际中高频出现:
-
H2 URL 缺少
;DB_CLOSE_DELAY=-1→ 多个@Test方法间数据库被清空 -
误用
jdbc:h2:mem:不带数据库名(如jdbc:h2:mem:) → 每次连接都是全新独立内存库,无法共享数据 -
未设置
spring.sql.init.mode→ Spring Boot 2.5+ 默认禁用 SQL 初始化,schema.sql不再自动执行 -
混合使用
@SpringBootTest和@DataJpaTest→ 前者加载全上下文,后者更轻量;按需选择,勿叠加
不复杂但容易忽略。

















