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

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. kubernetes进阶(03)kubernetes的namespace

    服务发现与负载均衡Kubernetes在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了Service资源,并通过kube-proxy配合cloud provider来适应不同的应用场景. ...

  2. ELK学习总结(1-2)安装ElasticSearch

    1.下载安装      Centos6.4      jdk1.8.20以上 elasticsearch::https://www.elastic.co/downloads/elasticsearch ...

  3. websocketj--随时随地在Web浏览器中操作你的服务端程序

    0 - 有没有觉得Linux标准终端界面输入输出枯燥无味? 1 - 什么?vmstat命令的输出数据不直观?有没有想过能够可视化该命令的输出? 2 - 尝试过用浏览器操作Windows中的cmd吗? ...

  4. multiprocessing.Process() ----------python中的多进程

    python 当中 使用封装好的 multiprocessing 为我们实现创建多进程任务. 1 Process()方法创建子进程 使用multiprocessing.Process() 方法产生一个 ...

  5. 深入理解Javascript单线程谈Event Loop

    假如面试回答js的运行机制时,你可能说出这么一段话:"Javascript的事件分同步任务和异步任务,遇到同步任务就放在执行栈中执行,而碰到异步任务就放到任务队列之中,等到执行栈执行完毕之后 ...

  6. win10下安装Ubuntu16.04双系统

    其实我是不喜欢系统的,之前都是在win下面进行开发,现在来了个项目,经过各种环境的安装调研,最终选择在Ubuntu下面进行开发.之前想着为啥不在虚拟机里面安装Ubuntu进行操作呢,由于虚拟机的体验不 ...

  7. 关于vertical-align和line-height的真知灼见

    本文的重点是了解vertical-align和line-height的使用 涉及到的名词:基线,底端,行内框,行框,行间距,替换元素及非替换元素,对齐.只有充分理解这些概念才会灵活运用这两个属性. 什 ...

  8. Tensorflow计算模型 —— 计算图

    转载自:http://blog.csdn.net/john_xyz/article/details/69053626 Tensorflow是一个通过计算图的形式来表述计算的编程系统,计算图也叫数据流图 ...

  9. 什么是web框架

    什么是web框架 web应用框架是支持动态网站.网络应用程序的软件框架. web框架的工作方式:接收http请求并处理,分派代码, 产生html,创建http响应. web框架 通常包含了:url路由 ...

  10. 有没有想过css定位与xpath的区别

    我是这样理解的, css选择如同你尽可能具体的描述一个元素的形态, 包括他的: 标签, 类, id 以及这些的组合, 目标是尽可能确定元素的唯一坐标 , 以方便选择. 而xpath是根据元素的路径去确 ...