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

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. Spring Security入门(2-3)Spring Security 的运行原理 4 - 自定义登录方法和页面

    参考链接,多谢作者: http://blog.csdn.net/lee353086/article/details/52586916 http元素下的form-login元素是用来定义表单登录信息的. ...

  2. 页面加载loading动画

    关于页面加载的loading动画,能度娘到的大部分都是通过定时器+蒙层实现的,虽然表面上实现了动画效果,实际上动化进程和页面加载进程是没有什么关系的,只是设置几秒钟之后关闭蒙层,但假如页面须要加载的元 ...

  3. 高级控件之Scrollview ( 滑动屏幕 ) 与 Imageview (滑动屏幕 切换图片)

    ScrollView  的xml布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayo ...

  4. lambda匿名函数透析

    lambda匿名函数透析 目录 1       匿名函数的作用... 1 2       匿名函数的格式... 1 3       匿名函数实例代码... 3   1         匿名函数的作用 ...

  5. 安卓手机USB共享网络给PC上网

    开端 哈哈,最近我又发现了一个校园网的漏洞,但是只能手机连接,于是就想手机连接之后通过usb共享给电脑上网. 在手机上连接校园网WiFi,开启USB网络共享并且连接电脑之后,却发现电脑十分的卡顿!CP ...

  6. switchysharp设置

    在线规则列表里面插入下面的网址:https://autoproxy-gfwlist.googlecode.com/svn/trunk/gfwlist.txt

  7. UVA-624 CD---01背包+输出路径

    题目链接: https://vjudge.net/problem/UVA-624 题目大意: 这道题给定一个时间上限,然后一个数字N,后面跟着N首歌的时间长度,要我们 求在规定时间w内每首歌都要完整的 ...

  8. [转]pycharm常用快捷键及设置

    PyCharm3.0默认快捷键(翻译的) PyCharm Default Keymap 1.编辑(Editing) Ctrl + Space    基本的代码完成(类.方法.属性)Ctrl + Alt ...

  9. 瞎扯设计模式1:单例模式 饿汉模式 懒汉模式 线程安全的单例 singleton 设计模式 java

    [原创声明]此文为本人原创,欢迎转载,转载请注明出处,作者链接~ http://www.cnblogs.com/m-yb/p/8833085.html 单例很常用,面试也经常被问,如:不用自定义锁怎么 ...

  10. 3.3.4 配置Tomcat的<Context>元素 (转)

    本章3.3.2节已经介绍了在Tomcat中发布JavaWeb应用的最快捷的方式,即只需把JavaWeb应用的所有文件复制到<CATALINA_HOME>/webapps目录下即可,Tomc ...