h2 数据库#
H2是一个采用java语言编写的嵌入式数据库引擎,只是一个类库(即只有一个 jar 文件),可以直接嵌入到应用项目中,不受平台的限制
应用场景#
- 可以同应用程序打包在一起发布,可以非常方便地存储少量结构化数据
- 可用于单元测试
- 可以用作缓存,即当做内存数据库
连接模式#
tcp 服务模式#
服务器模式(Server Mode):使用服务器模式和内嵌模式一样,它可以跑在另一个进程里
- 启动一个h2 作为server模式
java -classpath h2-2.1.212.jar org.h2.tools.Server -ifNotExists -tcp -tcpPort 9092 -tcpAllowOthers -web -webPort 8092 -browser -webAllowOthers参数说明#
-ifNotExists允许自动创建数据库-tcp启动tcp连接访问模式, 其他应用可以使用tcp方式连接到h2-tcpPorttcp连接端口号-tcpAllowOthers允许多个tcp连接-web启动web控制台-webPortweb访问端口号-browser浏览器访问-webAllowOthersweb控制台允许多个访问
内存模式#
内嵌模式(Embedded Mode):内嵌模式下,应用和数据库同在一个JVM中,通过JDBC进行连接。可持久化,但同时只能一个客户端连接。内嵌模式性能会比较好

使用#
作为服务端使用#
- tcp模式首先要使用启动命令来启动一个h2服务端, 供其他应用使用tcp方式连接才可以
- 启动成功后会在
jdbc url指定的目录生成俩个文件*.mv.db和*.trace.db, 前者是数据存储文件后者是日志文件 - h2会在
~目录(当前用户目录)生成配置记录文件.h2.server.properties, windows在C:\Users\用户名\, linux 在/Users/用户名/
与spring-boot集成#
- yaml配置文件, 下面使用的是内存模式
spring: datasource: url: jdbc:h2:mem:chore;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE #mem:连接到内存# url: jdbc:h2:file:~/chore;MODE=MySQL;AUTO_SERVER=true #file 连接到文件# url: jdbc:h2:tcp://localhost/~/DevSoftWare/developer/h2-data/chore;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE # tcp 连接到tcp driver-class-name: org.h2.Driver username: olsond password: 123456 # spring-boot2.5.x以下版本使用 # schema: classpath: classpath:db/schema.sql # springboot2.5.x以上版本已弃用spring.datasource.schema属性,可以使用以下配置初始化sql sql: init: mode: always schema-locations: ['classpath:db/schema.sql'] data-locations: ['classpath:db/init.sql'] h2: console: enabled: true # 开启web访问控制台 path: /h2-console- 启动服务springboot服务后,访问地址 http://ip:port/h2-console, 使用
spring.datasource.url即可使用web控制台访问h2数据库(内存模式)
使用过程的问题#
无法创建数据库#
- 启动tcp模式一定要加上参数
-ifNotExists, 否则首次启动访问数据库, 提示数据库文件不存在
mysql语法不兼容#
场景#
- 在应用启动加载
schema.sql的初始脚本是mysql语法的, 启动直接就报错了,语法如下
DROP TABLE IF EXISTS TEST;CREATE TABLE TEST( ID INT PRIMARY KEY comment '主键', NAME VARCHAR(255) not null comment '名字');- 连接配置
jdbc:h2:tcp://localhost/~/DevSoftWare/developer/h2-data/chore;MODE=MySQL, 指定了MODE=Mysql配置, 访问web控制台操作也是出现同样的错误,不兼容mysql语法, 使用的h2版本是h2-1.4.199.jar

解决方案#
- 调整支持h2的语法
DROP TABLE IF EXISTS TEST;CREATE TABLE TEST( ID INT PRIMARY KEY comment '主键', NAME VARCHAR(255) not null comment '名字');
COMMENT on TABLE TEST is 'demo';COMMENT on COLUMN TEST.ID is '主键';COMMENT on COLUMN TEST.NAME is '名字';**注意: 表注释还是需要单独声明
COMMENT on TABLE tablename is ''
- 或者升级高版本的h2, 使用
h2-2.1.212.jar即使连接配置不指定MODE=Mysql也可以支持mysql语法, 说明是h2的版本问题导致的