2019独角兽企业重金招聘Python工程师标准>>>
前言
前几个星期, 搭建项目的单元测试配置, 打算使用H2做为内存数据库来跑单元测试, 但是项目使用的是MYSQL数据库, Navicat导出的sql不兼容H2数据库, 所以需要转换. 经过了一些常识, 写了个工具类类转换.
准备
- 工具不一定能处理所有情况.
- 需要先将MYSQL的建表语句通过Navicat导出, 具体为,
右键数据库 -> Dump SQL File -> Structure Only
导出仅包含建表语句的SQL文件. - 运行下面代码.
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
/**
* 转换navicat导出的mysql的建表语句为h2的语法
*
* 主要的要注意的点是:
*
* 1.设置H2为mysql模式, 可以通过 SET MODE MYSQL;语句来实现
*
* 2.'`'全部要去掉
*
* 3.字段的字符集设置'COLLATE utf8_bin'不支持, 需要删除, 如这样的'`operator` varchar(10) COLLATE utf8_bin NOT NULL'
*
* 4.注释按道理也没问题的, 但是没有用, 所以删除了.
*
* 5.'ENGINE=InnoDB'设置不支持, 删掉
*
* 6.'DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'不支持, 修改为H2类似的'AS CURRENT_TIMESTAMP'
*
* 7.H2的索引名必须要全局唯一, 所以需要替换所有的索引名为全局唯一
*
* @author tudesheng
* @since 2016年6月20日 下午8:37:52
*
*/
public class TransformMysqlToH2 {
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\haogrgr\\Desktop\\你的sql文件");
String content = Files.toString(file, Charsets.UTF_8);
content = "SET MODE MYSQL;\n\n" + content;
content = content.replaceAll("`", "");
content = content.replaceAll("COLLATE.*(?=D)", "");
content = content.replaceAll("COMMENT.*'(?=,)", "");
content = content.replaceAll("\\).*ENGINE.*(?=;)", ")");
content = content.replaceAll("DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP", " AS CURRENT_TIMESTAMP");
content = uniqueKey(content);
System.out.println(content);
}
/**
* h2的索引名必须全局唯一
*
* @param content sql建表脚本
* @return 替换索引名为全局唯一
*/
private static String uniqueKey(String content) {
int inc = 0;
Pattern pattern = Pattern.compile("(?<=KEY )(.*?)(?= \\()");
Matcher matcher = pattern.matcher(content);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, matcher.group() + inc++);
}
matcher.appendTail(sb);
content = sb.toString();
return content;
}
}
最后
代码比较简单, 注释里面有说明, 不一定能处理所有情况, 但是我这里是可以了.