选H2因其Java原生实现、无native依赖、启动快、内存占用低,适合测试与轻量应用;SQLite需JNI,Derby对JDK版本敏感;H2默认不兼容MySQL语法,需MODE参数启用兼容模式。

为什么选 H2 而不是 SQLite 或 Derby
H2 是 Java 原生实现的嵌入式数据库,不需要额外 native 依赖,启动快、内存占用低,适合单元测试、原型开发和轻量级桌面应用。H2 的 JDBC URL 格式统一(jdbc:h2:mem:、jdbc:h2:file:),驱动类名固定为 org.h2.Driver,不像 SQLite 需要 JNI 库,也不像 Derby 对 JDK 版本敏感。
常见误区是直接把 H2 当成 MySQL 用——它默认不兼容 MySQL 语法,比如 INSERT IGNORE、ON DUPLICATE KEY UPDATE 都不支持,除非显式启用兼容模式。
如何配置内存模式与文件模式的连接 URL
内存模式适合测试,进程退出即丢数据;文件模式持久化,但要注意路径权限和相对路径解析逻辑(H2 默认以 JVM 启动目录为基准)。
-
jdbc:h2:mem:testdb—— 纯内存,每次新建连接都是新库,需加;DB_CLOSE_DELAY=-1才能让多个连接共享同一内存实例 -
jdbc:h2:file:./data/sample—— 写入当前目录下的sample.mv.db文件,推荐加;AUTO_SERVER=TRUE支持多进程访问(避免Database may be already in use错误) -
jdbc:h2:~/test—— 使用用户主目录,路径更稳定,适合桌面应用
注意:URL 中不能漏掉冒号,jdbc:h2:mem 会报 File not found;文件模式首次连接会自动建库,但目录必须存在,否则抛 java.io.IOException: Directory doesn't exist。
立即学习“Java免费学习笔记(深入)”;
怎样让 H2 兼容 MySQL 或 PostgreSQL 语法
H2 提供 MODE 参数模拟其他数据库行为,但只是语法层适配,底层仍是 H2 引擎,别指望执行计划或锁机制一致。
- MySQL 模式:
jdbc:h2:mem:test;MODE=MySQL→ 支持INT(11)、TINYINT、ENGINE=InnoDB(忽略)、反引号标识符 - PostgreSQL 模式:
jdbc:h2:mem:test;MODE=PostgreSQL→ 支持SERIAL、双引号字段名、ILIKE - 关闭大小写敏感:
;DATABASE_TO_UPPER=false,否则建表CREATE TABLE User会被转成USER,查select * from User就报错
MODE 必须在连接 URL 里指定,运行时无法切换;启用 MODE 后,部分 H2 特有函数(如 DATEADD)可能被禁用或行为改变。
使用 H2 Console 查看和调试数据的正确姿势
H2 Console 是内嵌 Web 控制台,不是所有场景都开得起来——它依赖 Servlet 容器,Spring Boot 项目默认只在 devtools 下启用,普通 Java SE 程序得手动启动。
- Spring Boot:确保
spring.h2.console.enabled=true,访问http://localhost:8080/h2-console,JDBC URL 填你代码里用的那个(如jdbc:h2:mem:testdb),不要填jdbc:h2:mem:空库名 - Java SE:调用
org.h2.tools.Server.createWebServer("-web"),然后在浏览器打开http://localhost:8082,注意端口冲突 - Console 默认允许任意 JDBC URL 连接,生产环境务必禁用(
spring.h2.console.enabled=false)或加反向代理鉴权
一个容易忽略的点:Console 连接的是“另一个连接”,它不会自动继承你代码里已建的表结构或数据——如果用了内存库且没设 ;DB_CLOSE_DELAY=-1,Console 连上去就是空库。










