项目版本升级过程中低版本数据库表升级成高版本数据库表的解决

  项目2个版本的代差较大,。要把客户生成环境升级成高版本。要把高版本累加的表结构同步到客户低版本生产环境。又不能影响客户生产环境的原有数据。

方案:
1> 用多数据源把2个版本的表和列定义读出来。
2>在代码里进行分析低版本缺失的表和字段,并生成脚本。

简单的多数据源+查表元数据+代码分析应用。实用有效。逻辑部很很简单,简单的包含与不包含判断是否需要添加删除。
// 读取表的元数据

public class TableMaterial {
	//低版本的表集合
    private List<String> v4tableNames = new ArrayList<>();
	//低版本的表与列的关系映射
    private Map<String, List<GenTableColumn>> v4TableColumns = new HashMap<>();
	//高版本表集合
    private List<String> v41tableNames = new ArrayList<>();
	//高版本表映射
    private Map<String, List<GenTableColumn>> v41TableColumns = new HashMap<>();

//分析缺失的表

public class AddTableDropTableAnalyser implements VersionAnalyser {

    public void analyser(TableMaterial tableMaterial) {
        List<String> v4tableNames = tableMaterial.getV4tableNames();
        List<String> v41tableNames = tableMaterial.getV41tableNames();
		//低版本需要补建的表,这里只是在公司把要建的表弄到一个单独的库里,再从单独的库里导出详细的建表语句。所以用了like建表。
        StringBuffer addTableMessages = new StringBuffer();
        String createTableSql = "create table %s like xxx.%s;" + System.lineSeparator();
        for (String v41tableName : v41tableNames) {
            if (!v4tableNames.contains(v41tableName)) {
                addTableMessages.append(String.format(createTableSql, v41tableName, v41tableName));
            }
        }
        FileUtils.addContent("41版本比对40版本添加的表.sql", addTableMessages.toString());

		// 删除的表,这部份脚本没必要在低版本执行。
        StringBuffer delTableMessages = new StringBuffer();
        String dropTableSql = "drop table %s;" + System.lineSeparator();
        for (String v4tableName : v4tableNames) {
            if (!v41tableNames.contains(v4tableName)) {
                delTableMessages.append(String.format(dropTableSql, v4tableName));
            }
        }
        FileUtils.addContent("41版本比对40版本删除的表.sql", delTableMessages.toString());
    }
}

//分析缺失的字段

public class ColumnInfoAnalyser implements VersionAnalyser {

    private StringBuffer addColumns = null;
    private StringBuffer dropColumns = null;

    @Override
    public void analyser(TableMaterial tableMaterial) {
        addColumns = new StringBuffer();
        dropColumns = new StringBuffer();
		// 低版本表和字段
        Map<String, List<GenTableColumn>> v4TableColumns = tableMaterial.getV4TableColumns();
		// 高版本表和字段
        Map<String, List<GenTableColumn>> v41TableColumns = tableMaterial.getV41TableColumns();

        v41TableColumns.forEach((tableName, v41Columns) -> {
            if (v4TableColumns.containsKey(tableName)) {
                List<GenTableColumn> v4Columns = v4TableColumns.get(tableName);
                toAnalyserCloumn(tableName, v4Columns, v41Columns);
            }
        });
        FileUtils.addContent("要添加的字段.sql", addColumns.toString());
        // 实际没有执行该脚本。有少许脏数据。没啥影响。
        FileUtils.addContent("要移除字段.sql", dropColumns.toString());
    }

    private void toAnalyserCloumn(String tableName, List<GenTableColumn> v4Columns, List<GenTableColumn> v41Columns) {
        List<String> v4ColumnNames = new ArrayList<>();
        List<String> v41ColumnNames = new ArrayList<>();

        for (GenTableColumn v4Column : v4Columns) {
            v4ColumnNames .add(v4Column.getColnmnName().toLowerCase());
        }

        for (GenTableColumn v41Column : v41Columns) {
            v41ColumnNames.add(v41Column.getColnmnName().toLowerCase());
        }

        for (GenTableColumn v41Column : v41Columns) {
            String columnName = v41Column.getColnmnName().toLowerCase();
            if (!v4ColumnNames .contains(columnName)) {
                String jdbcType = v41Column.getJdbcType();
                String columnType = jdbcType.toLowerCase();
                String sql = "alter table %s add %s  %s;" + System.lineSeparator();

                if (jdbcType.contains("char")) {
                    Long colnmnLength = v41Column.getColnmnLength();
                    jdbcType = jdbcType + "(" + colnmnLength + ")";
                }
                String format = String.format(sql, tableName, columnName, jdbcType);
                addColumns.append(format);
            }
        }

        for (GenTableColumn v41Column : v4Columns) {
            String colnmnName = v41Column.getColnmnName().toLowerCase();
            if (!v41ColumnNames.contains(colnmnName)) {
                String sql = "alter table %s drop %s ;" + System.lineSeparator();
                dropColumns.append(String.format(sql, tableName, colnmnName));
            }
        }
    }
}

//文件生成效果:
在这里插入图片描述

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值