今天研究了一下不同数据库之间如何做同步。弄了一个升级工具类,希望以后还能有所帮助。

public class UpgradeDataBase {

    public static void main(String[] args) {
//两个不同数据库名称
List<String> sqls = UpgradeDataBaseToStandardDataBase("database1", "database2");
for(String sql : sqls) {
System.out.println(sql);
}
} /**
* 将基准库里有的表字段,以名称为基准,生成同步到目标库中的脚本
*/
public static List<String> UpgradeDataBaseToStandardDataBase(String standard, String target) { List<String> upgradeSqls = new ArrayList<>(); List<String> standardTables = new ArrayList<>();
List<String> targetTables = new ArrayList<>(); Connection connStandard = null;
Connection connTarget = null; Statement stmtStandard = null;
Statement stmtTarget = null; ResultSet rsStandard = null;
ResultSet rsTarget = null; try {
Properties props = Resources.getResourceAsProperties("jdbc.properties");
String url = props.getProperty("url");
String driver = props.getProperty("driver");
String username = props.getProperty("username");
String password = props.getProperty("password"); Class.forName(driver).newInstance();
//拿到2个库的链接
connStandard = DriverManager.getConnection(url, username, password);
connStandard.setCatalog(standard); connTarget = DriverManager.getConnection(url, username, password);
connTarget.setCatalog(target); stmtStandard = connStandard.createStatement();
stmtTarget = connTarget.createStatement(); //先把2个库所有的表查出来
stmtStandard.execute("show tables");
stmtTarget.execute("show tables"); rsStandard = stmtStandard.getResultSet();
rsTarget = stmtTarget.getResultSet(); while (rsStandard.next()){
standardTables.add(rsStandard.getString(1));
} while (rsTarget.next()){
targetTables.add(rsTarget.getString(1));
}
//循环基准库中每一张表
for(String table : standardTables) {
if("SM_USER".equals(table)) {
continue;
}
if(targetTables.contains(table)) {
Map<String, Map<String, String>> standardColumns = new HashMap<>();
Map<String, Map<String, String>> targetColumns = new HashMap<>();
//检查每一个字段,
//1.首先先查出目标库和基准库该表的所有字段
stmtStandard.execute("show columns from " + table + " from " + standard);
rsStandard = stmtStandard.getResultSet();
while (rsStandard.next()){ Map<String, String> map = new HashMap<>();
map.put("Field", rsStandard.getString("Field"));//列名
map.put("Type", rsStandard.getString("Type"));//类型+长度
map.put("Null", rsStandard.getString("Null"));//是否可为空
map.put("Key", rsStandard.getString("Key"));//是否主键
map.put("Default", rsStandard.getString("Default"));//默认值
map.put("Extra", rsStandard.getString("Extra"));//其他(自增列,触发器等)
standardColumns.put(rsStandard.getString("Field"), map);
} stmtTarget.execute("show columns from " + table + " from " + target);
rsTarget = stmtTarget.getResultSet();
while (rsTarget.next()){ Map<String, String> map = new HashMap<>();
map.put("Field", rsTarget.getString("Field"));//列名
map.put("Type", rsTarget.getString("Type"));//类型+长度
map.put("Null", rsTarget.getString("Null"));//是否可为空
map.put("Key", rsTarget.getString("Key"));//是否主键
map.put("Default", rsTarget.getString("Default"));//默认值
map.put("Extra", rsTarget.getString("Extra"));//其他(自增列,触发器等)
targetColumns.put(rsTarget.getString("Field"), map);
} //2.以基准库为准,逐个列比较
//TODO 没有处理Key(没有做主键、自增处理)
for(String column : standardColumns.keySet()) {
if(targetColumns.containsKey(column)) {//存在这一列
boolean needGeneSql = false;
StringBuffer buffer = new StringBuffer();
//类型有变化, 但是不管类型有没有变化,后续的语句都需要
// if(standardColumns.get(column).get("Type") != null && !standardColumns.get(column).get("Type").equals(targetColumns.get(column).get("Type"))) {
// buffer.append(standardColumns.get(column).get("Type"));
// }
buffer.append(standardColumns.get(column).get("Type"));
//默认值有变
if(standardColumns.get(column).get("Default") != null && !standardColumns.get(column).get("Default").equals(targetColumns.get(column).get("Default"))) {
buffer.append(" default " + standardColumns.get(column).get("Default"));
needGeneSql = true;
}
//是否可空有变
if(standardColumns.get(column).get("Null") != null && !standardColumns.get(column).get("Null").equals(targetColumns.get(column).get("Null"))) {
buffer.append(("NO".equals(standardColumns.get(column).get("Null")) ? " not null " : " null "));
needGeneSql = true;
}
//处理自增长等
if(standardColumns.get(column).get("Extra") != null && !standardColumns.get(column).get("Extra").equals(targetColumns.get(column).get("Extra"))) {
buffer.append(" ").append(standardColumns.get(column).get("Extra"));
needGeneSql = true;
}
if(needGeneSql) {
String changeColumnSql = "alter table " + table + " change " + column + " " + column + " " + buffer.toString() + ";";
upgradeSqls.add(changeColumnSql);
}
}
else{
String addColumnSql = "alter table " + table +
" add column " + column + " " +
standardColumns.get(column).get("Type") + " default " + standardColumns.get(column).get("Default") +
("NO".equals(standardColumns.get(column).get("Null")) ? " not null " : " null ") + ";";
upgradeSqls.add(addColumnSql);
}
}
}
else{//目标库中,没有基准库的表
stmtStandard.execute("show create table " + table);
rsStandard = stmtStandard.getResultSet();
String createSql = null;
while (rsStandard.next()){
//第2列是建表语句
createSql = rsStandard.getString(2);
upgradeSqls.add(createSql + ";");
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rsStandard.close();
rsTarget.close();
stmtStandard.close();
stmtTarget.close();
connStandard.close();
connTarget.close();
} catch (SQLException e) {
e.printStackTrace();
} }
return upgradeSqls; }
}

  

  

Mysql根据一个基库生成其他库与其不同的库升级脚本的更多相关文章

  1. Linux静态库生成指南

    Linux静态库生成指南   Linux上的静态库,其实是目标文件的归档文件.在Linux上创建静态库的步骤如下: 写源文件,通过 gcc -c xxx.c 生成目标文件. 用 ar 归档目标文件,生 ...

  2. iOS 静态库生成(引用第三方SDK、开源库、资源包)

    一.静态库创建 打开Xcode, 选择File ----> New ---> Project  选择iOS ----> Framework & Library ---> ...

  3. QRCode.js一个生成二维码的javascript库

    前言 最近在开发中遇到一个需求:将后端返回的链接转换成二维码,那么如何来实现呢?我们可以使用QRCode.js来解决这一问题 什么是 QRCode.js? QRCode.js 是一个用于生成二维码的 ...

  4. Linux下动态库生成和使用

    Linux下动态库生成和使用 一.动态库的基本概念 1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序.动态链接库是目标文件的集合,目标文件在动态链接库中 ...

  5. Linux下静态库生成和使用

    Linux下静态库生成和使用 一.静态库概念 1.库是预编译的目标文件(object  files)的集合,它们可以被链接进程序.静态库以后缀为”.a”的特殊的存档(archive file)存储. ...

  6. PHP5 GD库生成图形验证码(汉字)

    PHP5 GD库生成图形验证码且带有汉字的实例分享. 1,利用GD库函数生成图片,并在图片上写指定字符imagecreatetruecolor 新建一个真彩色图像imagecolorallocate ...

  7. Windows环境下编译Assimp库生成Android可用的.so或.a文件

    在做项目过程中需要使用Assimp这个3D模型读取库来读取obj格式的模型,因为项目是基于Android平台,采用NDK开发,所以就打算编译Assimp库并生成.so文件.本文使用Assimp-v.5 ...

  8. Linux动态库生成与使用指南

    相关阅读: Linux静态库生成指南 Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件. 在链接动态库生成可执行文件时,并不 ...

  9. PHP验证码生成及图片处理(GD库)

    GD库是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片,也可以给图片加水印. 本章实现了生成图片并绘画各种形状.图片的压缩.中文字符水印及图片水印 ...

随机推荐

  1. Docker学习笔记 - Docker的仓库

  2. docker实践

    我的docker 学习笔记2   ps axf docker run -d cyf:sshd /usr/sbin -D   docker  ps docker-enter.sh 686 ps axf ...

  3. ssh整合之二hibernate单独搭建

    1.首先我们需要去拷贝我们的hibernate所需的jar包  这里还需要加入我们C3P0的jar包,因为我们hibernate中使用的C3P0连接池 2. 编写我们的关系映射文件Customer.c ...

  4. windows下nginx代理ftp服务器

    我所在的开发环境里,nginx和ftp在同一台服务器. ftp根目录: nginx的配置: 在nginx.conf中加入: server { listen ; server_name localhos ...

  5. linux文件访问权限(像rw-r--rw-是什么意思)

    Linux的文件访问权限分为 读.写.执行三种 r:可读(4) w:可写(2)对目录来说则可新建文件 x:可执行(1)对目录来说则可进入该目录 可用 ls -l 查看文件 像上图的-rw-r--rw- ...

  6. Beautiful Soup常见的解析器

    Beautiful Soup支持Python标准库中的HTML解析器,还支持一些第三方的解析器,如果我们不安装它,则 Python 会使用 Python默认的解析器,lxml 解析器更加强大,速度更快 ...

  7. Python面向对象——多重继承

    1本文的作用 一个从多个父类继承过来的子类,可以访问所有父类的功能. 2图文介绍 3代码验证 class Contact: all_contacts = [] def __init__(self, n ...

  8. Python求解啤酒问题(携程2016笔试题)

    问题描述:一位酒商共有5桶葡萄酒和1桶啤酒,6个桶的容量分别为30升.32升.36升.38升.40升和62升,并且只卖整桶酒,不零卖.第一位顾客买走了2整桶葡萄酒,第二位顾客买走的葡萄酒是第一位顾客的 ...

  9. 创建类似于Oracle中decode的函数

    -- 创建类似于Oracle中decode的函数create or replace function decode(variadic p_decode_list text[])returns text ...

  10. JS实现数组去重方法总结(六种方法)

    方法一: 双层循环,外层循环元素,内层循环时比较值 如果有相同的值则跳过,不相同则push进数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Array. ...