选h2因其java原生实现、无native依赖、启动快、内存占用低,适合单元测试;默认不兼容mysql语法,需mode参数启用兼容模式。

Java 单元测试中连接内嵌数据库(如 H2、HSQLDB 或 Derby)是主流做法,既能避免依赖真实数据库,又能保证测试的隔离性、可重复性和执行速度。核心思路是:用内存数据库替代真实 DB,在测试启动时自动建表、预置数据,测试结束即销毁。
为什么选内嵌数据库做单元测试
真实数据库连接慢、易受环境干扰、多人共用易冲突;而 H2 等内嵌库启动快(毫秒级)、纯内存运行、支持标准 SQL 和 DDL,且可配置为“每次测试后重置”,天然适配单元测试生命周期。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
以 H2 为例的典型集成方式
使用 Spring Boot + JUnit 5 + H2 是最简实践路径,无需手动管理连接和事务:
- 在 pom.xml 中添加依赖:
<dependency><br> <groupid>com.h2database</groupid><br> <artifactid>h2</artifactid><br> <scope>test</scope><br></dependency>
- 在 src/test/resources/application-test.yml 配置 H2 内存实例:
spring:<br> datasource:<br> url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE<br> driver-class-name: org.h2.Driver<br> username: sa<br> password:<br> jpa:<br> database-platform: org.hibernate.dialect.H2Dialect<br> hibernate:<br> ddl-auto: create-drop # 每次测试前建表,结束后清空
- 测试类上加注解启用配置:
@SpringBootTest(classes = {YourConfig.class}, properties = "spring.profiles.active=test")<br>@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)(若用 @DataJpaTest 则更轻量,自动替换为 H2)
不依赖 Spring 的纯 JUnit 测试写法
适合非 Spring 项目或想完全掌控连接逻辑的场景:
- 直接用 JDBC 获取 H2 连接:
Connection conn = DriverManager.getConnection("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "sa", ""); - 用 Flyway 或纯 SQL 初始化表结构:
conn.createStatement().execute("CREATE TABLE user(id INT PRIMARY KEY, name VARCHAR(50))"); - 在 @BeforeEach 中插入测试数据,@AfterEach 中清空表(或直接用
jdbc:h2:mem:test;DB_CLOSE_DELAY=-1,每次 JVM 重启即重置)
关键注意事项
-
H2 URL 参数很重要:加上
DB_CLOSE_DELAY=-1可防止连接关闭时数据库被删;DB_CLOSE_ON_EXIT=FALSE避免 JVM 退出时丢失内存数据(对多测试类共享连接有帮助) -
DDL 与 DML 分离:建表建议用 schema.sql,初始数据用 data.sql,由 Spring Boot 自动执行(需开启
spring.sql.init.mode=always) -
避免跨测试污染:不用
ddl-auto: update,它可能因字段变更导致状态残留;推荐create-drop或显式DROP TABLE IF EXISTS -
兼容性检查:H2 默认语法接近 PostgreSQL,若用 MySQL 特有函数(如
IFNULL),需加参数;MODE=MySQL
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










