H2 Database
Overview
H2作为嵌入式数据库里性能最佳的选择,是开发期的最爱。
运行方式
嵌入式在内存中运行
在单元测试的嵌入式内存中运行,为求极致的速度,而且测试完后数据不会保留。
jdbc:h2:mem:DBName;DB_CLOSE_DELAY=-1
参数DB_CLOSE_DELAY是要求最后一个正在连接的连接断开后,不要关闭DB,因为下一个case可能还会有新连接进来。
注意在Springside里用了Spring的连消带打的写法,三行写完了datasource定义和初始化脚本。
可以定义多个嵌入式数据库,Spring会用定义中的id来做DBName。
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:sql/h2/schema.sql" />
</jdbc:embedded-database>
嵌入式但持久化到文件
但在Functional Test 和 日常开发环境中,如果Debug看不到数据,会很不方便。所以依然使用嵌入式,不需要手工启动Server,但数据会持久化到文件,这是最好用的模式。
jdbc:h2:file:~/.h2/DBName;AUTO_SERVER=TRUE
数据库文件保存在 ~/.h2/databaseName会在用户的Home目录下的.h2目录里创建database文件,也可以使用绝对路径。
Web Console
此时,就可以打开H2那个超好用的WebConsole来查阅数据. SpringSide的support/H2目录有其启动脚本,基本上是 "java -jar h2-1.3.168.jar -web -webPort 8090 -browser"的样子,但用了maven来运行。
多个进程访问同一个数据库文件 -- AUTO_SERVER=TRUE
又要开WebConsole,又要跑Web应用的情况下,本来会造成文件锁冲突的,好在有个AUTO_SERVER=TRUE的连接参数. 第一个打开数据库文件的进程,将自觉兼任H2 Server的角色,并把自己的地址和端口写到lock文件里, 第二个连进来的进程,发现lock文件存在,就会读取并通过网络方式来访问H2。
当然,第一个连进来的进程因为是直接访问数据库文件,性能会较好一些。
使用限制
因为H2如此好用,一般用作开发环境/功能测试环境的标配。
此时就需要同步生产环境的Oracle/Mysql脚本 与 H2的脚本,表较少时可以全手工维护,否则可以写些Ant/Python脚本来维护,比如用正则表达式来replace掉一些mysql的多余定义。
如果不是使用Hibernate/JPA,而是使用Spring JDBC/MyBatis,而且使用了一些数据库特定语句时,H2就受限制了,Mybatis还好,支持为不同的数据库类型写不同的SQL, 如果是Spring JDBC,可能还是直接连MySQL/Oracle简单。