spring boot应用 从mysql迁移h2

此前有个应用用了mysql做数据存储,但实际存储的数据很少就几张表加起来一共几千行,并且一直没有修改的需求,应用内也只是进行查询。
实际上是静态的数据。

因为使用的是云服务商的产品,想着之后就不续费了需要将数据迁移。

有几个选项:

  1. 改用文件存储,读取到内存后处理;
  2. 换成嵌入式数据库。 1和2都需要将数据倒出并重新组织,并且1的成本更高需要修改之前DAL的逻辑。
    于是选择2,考虑是java的应用且需要和mysql有比较好的兼容,考虑使用H2

又因为数据量很少,占用内存不大,并且每次初始化也占用很少的时间,那考虑直接用内存的模式,应用启动的时候进行初始化。

迁移步骤

引入依赖

首先需要增加H2依赖。
pom.xml引入:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>${h2.version}</version>
</dependency>

修改配置

原先的配置需要从mysql迁移至H2.
application.properties中修改datasource配置:

spring.datasource.url=jdbc:h2:mem:dbname;MODE=MYSQL;DATABASE_TO_LOWER=TRUE

不需要配user和password.

表/数据迁移

这一步可以用数据库管理工具,例如datagripdbeaver等创建一个h2数据库做实验。
让spring初始化只需要在resources下放schema.sqldata.sql即可。
前者放表定义,后者放导入sql的语句。

表的DDL可以通过show create table table_name得到,或者用数据库管理工具导出即可。
兼容需要一定的修改:

  1. 去除unsigned
  2. timestamp/datetime的 ON UPDATE 语句不支持,因为这里不会更新直接去掉;
  3. 表的comment和charset去除;
  4. bit的默认值的b去除。

大致这么处理即可。
其他的部分基本兼容。

数据导入用mysqldump或者数据库管理工具倒出即可。
这一步因为只有整型,字符串,时间等类型也没有任何冲突。

将DDL放入schema.sql,初始化数据的sql放入data.sql即可。

应用SQL修改

应用用的是mybatis,进行测试,找出不兼容的语句。
比较多的是在H2"是表示列名,字符串修改为'即可,以及bit不需要b前缀。
因为没有更多复杂的查询,所以这一步还算顺利。

乱码处理

因为导入的sql文件有编码,在不同平台file.encoding的值不一致,会出现导入的数据乱码的问题。
一般把sql文件设置为UTF-8,应用启动时指定-Dfile.encoding=utf-8即可(java -jar启动系统参数要放在jar包前,不然无效)。
或者在main中用 System.setProperty("file.encoding", "utf-8"); 指定。

参考资料

Exporting from MySQL to H2
Spring Boot With H2 Database