Java 工具类:SqlFileCompareUtils(比较数据库表和字段变化)

文章描述了一个Java程序,用于比较两个SQL文件中的表结构差异,包括表的增删和字段类型的变更,并输出详细的变化信息。
摘要由CSDN通过智能技术生成
    if (msg != null) {

        System.err.println(msg);

        return;

    }

    // 获取源 sql 文件的表字段信息

    Map<String, Map<String, String>> fromMap = getTableMap(sqlFileNameFrom);

    // 获取目标 sql 文件的表字段信息

    Map<String, Map<String, String>> toMap = getTableMap(sqlFileNameTo);

    // 比较两个 sql 文件的字段信息

    List<String> differenceList = getDifferenceList(fromMap, toMap);

    if (differenceList.isEmpty()) {

        System.out.println("表和字段无变化");

        return;

    }

    int size = differenceList.size();

    System.out.println("共变化 " + size + "处,具体如下:");

    for (int i = 0; i < size; i++) {

        System.out.println(String.format("【%s】%s", (i + 1), differenceList.get(i)));

    }

}



private static List<String> getDifferenceList(Map<String, Map<String, String>> fromMap,

        Map<String, Map<String, String>> toMap) {

    List<String> list = new ArrayList<String>();

    Set<String> toTableSet = toMap.keySet();

    for (String tableName : toTableSet) {

        Map<String, String> fromFieldMap = fromMap.get(tableName);

        // 如果目标文件有该表,源文件没有该表,则表已被删除,冗余

        if (fromFieldMap == null) {

            list.add("多余表:" + tableName);

        }

        // 继续比较表的字段

        Map<String, String> toFieldMap = toMap.get(tableName);

        List<String> fieldList = getDifferenceFieldList(tableName, fromFieldMap, toFieldMap);

        if (!fieldList.isEmpty()) {

            list.addAll(fieldList);

        }

    }

    // 新增表

    Set<String> fromTableSet = fromMap.keySet();

    fromTableSet.removeAll(toTableSet);

    for (String tableName : fromTableSet) {

        list.add("新增表:" + tableName);

    }

    return list;

}



private static List<String> getDifferenceFieldList(String tableName, Map<String, String> fromMap,

        Map<String, String> toMap) {

    List<String> list = new ArrayList<String>();

    Set<String> toFiledSet = toMap.keySet();

    for (String filedName : toFiledSet) {

        String fromFileType = fromMap.get(filedName);

        // 如果目标文件表有该字段,源文件表没有该字段,则该字段已被删除,冗余

        if (fromFileType == null) {

            list.add("%s 表多余字段:" + fromFileType);

            continue;

        }

        // 继续比较字段类型

        String toFileType = toMap.get(filedName);

        if (!fromFileType.equals(toFileType)) {

            list.add(String.format("%s 表字段变化:%s : %s -> %s", tableName, filedName, toFileType, fromFileType));

        }

    }

    // 新增字段

    Set<String> fromFiledSet = fromMap.keySet();

    fromFiledSet.removeAll(toFiledSet);

    for (String fromFiledName : fromFiledSet) {

        list.add(String.format("%s 表新增字段:%s : %s", tableName, fromFiledName, fromMap.get(fromFiledName)));

    }

    return list;

}



private static Map<String, Map<String, String>> getTableMap(String fileName) {

    String sqlFrom = getFileContent(fileName);

    Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();

    // 读取 sql 文件的所有行

    String[] lines = sqlFrom.split("\r\n");

    String tableName = null;

    for (String line : lines) {

        String trimLine = line.trim();

        // 以【CREATE TABLE】为开头的,则为表名

        if (trimLine.startsWith("CREATE TABLE")) {

            // 然后去掉 CREATE TABLE、`、( 即可获取表名

            tableName = trimLine.replaceAll("CREATE TABLE|`|\\(", "").trim();

            map.put(tableName, new HashMap<String, String>());

            continue;

        }

        // 以 ` 开头的,则为字段

        if (trimLine.startsWith("`")) {

            // 第 1 个 ` 和第 2 个 ` 之间的则为字段名

            String fieldName = getSplintIndexValue(trimLine, "`", 1);

            // 按 [空格] 拆分的第2个为字段类型

            String fieldType = getSplintIndexValue(trimLine, " ", 2);

            map.get(tableName).put(fieldName, fieldType);

        }

    }

    return map;

}



private static String getSplintIndexValue(String s, String regex, int index) {

    String[] strs = s.split(regex);

    int idx = 0;

    for (String str : strs) {

        if (!str.isEmpty()) {

            idx++;

        }

        if (idx == index) {

            return str;

        }

    }

    return "";

}



private static boolean isEmpty(String s) {

    return s == null || s.isEmpty();

}



private static String checkFile() {

    if (isEmpty(sqlFileNameFrom)) {

        return "源文件名称不能为空";

    }

    if (!sqlFileNameFrom.endsWith(".sql")) {

        return "源文件不是sql文件";

    }

    File from = new File(sqlFileNameFrom);

    if (!from.exists()) {

        return "源文件不存在于工程根目录下";

    }

    if (isEmpty(sqlFileNameTo)) {

        return "目标文件名称不能为空";

    }

    if (!sqlFileNameTo.endsWith(".sql")) {

        return "目标文件不是sql文件";

    }

    File to = new File(sqlFileNameTo);

    if (!to.exists()) {

        return "目标文件不存在于工程根目录下";

    }

    return null;

}



private static String getFileContent(String fileName) {

    File file = new File(fileName);

最后

   }

    return null;

}



private static String getFileContent(String fileName) {

    File file = new File(fileName);

最后

[外链图片转存中…(img-qYPuE9sV-1714124816209)]

[外链图片转存中…(img-U7n7wMtI-1714124816209)]

[外链图片转存中…(img-ENC4q02a-1714124816209)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值