Mysql根据一个基库生成其他库与其不同的库升级脚本
今天研究了一下不同数据库之间如何做同步。弄了一个升级工具类,希望以后还能有所帮助。
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根据一个基库生成其他库与其不同的库升级脚本的更多相关文章
- Linux静态库生成指南
Linux静态库生成指南 Linux上的静态库,其实是目标文件的归档文件.在Linux上创建静态库的步骤如下: 写源文件,通过 gcc -c xxx.c 生成目标文件. 用 ar 归档目标文件,生 ...
- iOS 静态库生成(引用第三方SDK、开源库、资源包)
一.静态库创建 打开Xcode, 选择File ----> New ---> Project 选择iOS ----> Framework & Library ---> ...
- QRCode.js一个生成二维码的javascript库
前言 最近在开发中遇到一个需求:将后端返回的链接转换成二维码,那么如何来实现呢?我们可以使用QRCode.js来解决这一问题 什么是 QRCode.js? QRCode.js 是一个用于生成二维码的 ...
- Linux下动态库生成和使用
Linux下动态库生成和使用 一.动态库的基本概念 1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序.动态链接库是目标文件的集合,目标文件在动态链接库中 ...
- Linux下静态库生成和使用
Linux下静态库生成和使用 一.静态库概念 1.库是预编译的目标文件(object files)的集合,它们可以被链接进程序.静态库以后缀为”.a”的特殊的存档(archive file)存储. ...
- PHP5 GD库生成图形验证码(汉字)
PHP5 GD库生成图形验证码且带有汉字的实例分享. 1,利用GD库函数生成图片,并在图片上写指定字符imagecreatetruecolor 新建一个真彩色图像imagecolorallocate ...
- Windows环境下编译Assimp库生成Android可用的.so或.a文件
在做项目过程中需要使用Assimp这个3D模型读取库来读取obj格式的模型,因为项目是基于Android平台,采用NDK开发,所以就打算编译Assimp库并生成.so文件.本文使用Assimp-v.5 ...
- Linux动态库生成与使用指南
相关阅读: Linux静态库生成指南 Linux下动态库文件的文件名形如 libxxx.so,其中so是 Shared Object 的缩写,即可以共享的目标文件. 在链接动态库生成可执行文件时,并不 ...
- PHP验证码生成及图片处理(GD库)
GD库是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片,也可以给图片加水印. 本章实现了生成图片并绘画各种形状.图片的压缩.中文字符水印及图片水印 ...
随机推荐
- eclipse+Maven插件报错:-Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment variable and mvn script match.
问题描述: eclipse indigo+maven3.3.3+jdk1.70 maven插件执行报错:-Dmaven.multiModuleProjectDirectory system prope ...
- 阿里云API网关(2)开放 API 并接入 API 网关
网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...
- 从微软MVP到女儿开学--2017前半年小结
2017年转眼就到了9月,原本在年初定的计划基本泡汤了. 看书啊减肥啊出教程啊,都被因为各种事物给缠身而没有完成. 1号带女儿去报名的时候,听到老师说"家长们请到这边来集合"的时候 ...
- 查看centos版本及32还是64位
1.[root@mini1 ~]# cat /etc/issue 2.[root@mini1 ~]# cat /etc/redhat-release 查看位数: [root@mini1 ~]# g ...
- R数据分析 第一篇:温习概率论
概率论是人们在长期实践中发现的理论,是客观存在的.自然界和社会上发生的现象是多种多样的,有一类现象,在一定条件下必然发生,称作确定性现象,而概率论研究的现象是不确定性现象,嗯嗯,醒醒,概率论研究的对象 ...
- 深度学习中Xavier初始化
"Xavier"初始化方法是一种很有效的神经网络初始化方法,方法来源于2010年的一篇论文<Understanding the difficulty of training ...
- 菜鸟容易中的招__setattr__
class Counter: def __init__(self): self.counter = 0 # 这里会触发 __setattr__ 调用 def __setattr__(self, nam ...
- JS查找字符串中出现次数最多的字符
本文给大家带来两种js中查找字符串中出现次数最多的字符,在这两种方法中小编推荐使用第二种,对js查找字符串出现次数的相关知识感兴趣的朋友一起看看吧 在一个字符串中,如 'zhaochucichuz ...
- C#调用Python,报错No module named os
C#调用Python 环境:Windows 8.1,已经安装Python2.7(C:\Python27),配置了环境变量. 已经安装VS2013,VS2017 1.安装IronPython 下载地址h ...
- Oracle中SQL调优(SQL TUNING)之最权威获取SQL执行计划大全
该文档为根据相关资料整理.总结而成,主要讲解Oracle数据库中,获取SQL语句执行计划的最权威.最正确的方法.步骤,此外,还详细说明了每种方法中可选项的意义及使用方法,以方便大家和自己日常工作中查阅 ...