转换MYSQL建表语句转换H2建表语句工具

前言

前几个星期, 搭建项目的单元测试配置, 打算使用H2做为内存数据库来跑单元测试, 但是项目使用的是MYSQL数据库, Navicat导出的sql不兼容H2数据库, 所以需要转换. 经过了一些常识, 写了个工具类类转换.

准备

  1. 工具不一定能处理所有情况.
  2. 需要先将MYSQL的建表语句通过Navicat导出, 具体为, 右键数据库 -> Dump SQL File -> Structure Only 导出仅包含建表语句的SQL文件.
  3. 运行下面代码.
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;
    }

}

最后

代码比较简单, 注释里面有说明, 不一定能处理所有情况, 但是我这里是可以了.

转载于:https://my.oschina.net/haogrgr/blog/707633

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值