mysql同步表到oracle
背景:使用sqldeveloper工具同步失败
实现:通过mysql元数据生成oracle建表语句
package com.concom.yunzq.impl;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SmallCatTest3 {
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://ip:3306/dbName?useUnicode=true&characterEncoding=utf8";
private static final String USERNAME = "root";
private static final String PASSWORD = "";
public static void main(String[] args) throws Exception {
String DateNow = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
System.out.println("-- 开始时间:" + DateNow);
Class.forName(DRIVER);
Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
DatabaseMetaData metaData = connection.getMetaData();
Map<String, List<TableInfo>> tableMap = getTableMap(metaData);
getOpDbSql(tableMap);
String DateEnd = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));
System.out.println("-- 结束时间:" + DateEnd);
System.err.println("--------执行结束--------");
}
private static void getOpDbSql(Map<String, List<TableInfo>> tableMap) throws IOException {
String newLine = "\r\n";
StringBuffer createTableText = new StringBuffer();
StringBuffer createPrimaryText = new StringBuffer();
StringBuffer createColumnText = new StringBuffer();
StringBuffer createTriggerText = new StringBuffer();
for (Map.Entry<String, List<TableInfo>> item : tableMap.entrySet()) {
createTableText.setLength(0);
createPrimaryText.setLength(0);
createColumnText.setLength(0);
createTriggerText.setLength(0);
createTableText.append("CALL PROC_DROPIFEXISTS('" + item.getKey() + "');"+newLine);
createTableText.append("create table " + item.getKey() + "(" + newLine);
int index = 0;
List<String> primaryList = new ArrayList<String>();
for (TableInfo table : item.getValue()) {
createTableText.append(" \"" + table.getFiled().toUpperCase() + "\" " + formateFiledType(table) + " " +formateDefaultValue(table.getDefaultValue()) + " " + formateIsNull(table.isNull()));
createTableText.append( (index + 1 != item.getValue().size()) ? ", " + newLine : newLine);
index ++;
if (table.isPrimaryKey()) {
primaryList.add(table.getFiled());
}
if (table.getRemark() != null && table.getRemark().length() > 0) {
createColumnText.append("comment on column " +item.getKey()+ "." + formateFiledKey(table.getFiled()) + " is '" + table.getRemark() + "';" + newLine);
}
}
createTableText.append(");" + newLine);
if (primaryList != null && primaryList.size() > 0) {
createPrimaryText.append("ALTER TABLE " + item.getKey() + " ADD PRIMARY KEY ("+String.join(",", primaryList)+");" + newLine);
}
createTriggerText.append(
"CALL PROC_DROPSEQUENCES_IFEXISTS('yunzq_metro_id_" + item.getKey() + "');"+ newLine +
"CREATE SEQUENCE yunzq_metro_id_" + item.getKey() + newLine +
" INCREMENT BY 1"+ newLine +
" START WITH 1"+ newLine +
" MAXVALUE 1.0E20"+ newLine +
" MINVALUE 1"+ newLine +
" NOCYCLE"+ newLine +
" CACHE 20"+ newLine +
" NOORDER ;"+ newLine +
" -- 触发器: " + newLine +
"CALL PROC_DROPTRIGGER_IFEXISTS('trigger_id_add_" + item.getKey() + "');"+ newLine +
"create or replace trigger trigger_id_add_" + item.getKey() + newLine +
"before insert on " + item.getKey() + newLine +
"for each row"+ newLine +
"begin"+ newLine +
"\tselect yunzq_metro_id_" + item.getKey() + ".nextval into :new.id from dual;"+ newLine +
"end;" + newLine
);
String path = "E:\\oracle\\table\\"+item.getKey()+".txt";
File file = new File(path);
if(!file.exists()){
file.getParentFile().mkdirs();
}else {
file.delete();
}
file.createNewFile();
FileWriter fw = new FileWriter(file, true);
fw.write("-- 创建表:" + item.getKey() + newLine + newLine);
fw.write(createTableText.toString());
fw.write(newLine + "-- 创建主键:" + newLine);
fw.write(createPrimaryText.toString());
fw.write(newLine + "-- 创建注释:" + newLine);
fw.write(createColumnText.toString());
fw.write(newLine + "-- 创建序列和触发器:" + newLine);
fw.write(createTriggerText.toString());
fw.flush();
fw.close();
}
}
private static String formateFiledKey(String filed) {
String returnString = "";
switch (filed.toUpperCase()) {
case "LEVER":
returnString = "\"LEVEL\"";
break;
case "NUMBER":
returnString = "\"NUMBER\"";
break;
case "DESC":
returnString = "\"DESC\"";
break;
case "RESOURCE":
returnString = "\"RESOURCE\"";
break;
default:
returnString = filed;
}
return returnString;
}
private static String formateFiledType(TableInfo table) {
String returnType = "";
switch (table.getFiledType()) {
case "INT":
returnType = "NUMBER(" + table.getFiledLenth() + ")";
break;
case "DATETIME":
returnType = "DATE";
break;
case "DATE":
returnType = "DATE";
break;
case "TIMESTAMP":
returnType = "DATE";
break;
case "TEXT":
returnType = "CLOB";
break;
case "LONGTEXT":
returnType = "CLOB";
break;
case "TINYINT":
returnType = "NUMBER(3)";
break;
case "BIGINT":
returnType = "NUMBER(20)";
break;
case "SMALLINT":
returnType = "NUMBER(5)";
break;
case "INT UNSIGNED":
returnType = "NUMBER(" + (table.getFiledLenth()>20 ? 20 : table.getFiledLenth()) + ")";
break;
case "DOUBLE":
returnType = "DECIMAL(" + (table.getFiledLenth()>20 ? 20 : table.getFiledLenth()) + "," + (table.getDecimalDigits() != null && table.getDecimalDigits().length() > 0 ? table.getDecimalDigits():"4") + ")";
break;
case "VARCHAR":
if (table.getFiledLenth() > 4000) {
returnType = "CLOB";
}else {
returnType = "VARCHAR2(" + table.getFiledLenth() + ")";
}
break;
case "FLOAT":
returnType = "DECIMAL(" + table.getFiledLenth() + ",10)";
System.err.println("---- 表名:" + table.getTableName() + " 列名:" + table.getFiled() +" 类型:" + table.getFiledType() + " 小数:"+table.getDecimalDigits() + " 出现异常!");
break;
case "CHAR":
returnType = "VARCHAR2(" + table.getFiledLenth() + ")";
break;
case "BIT":
returnType = "NUMBER(1)";
break;
case "DECIMAL":
returnType = "DECIMAL(" + (table.getFiledLenth()>20 ? 20 : table.getFiledLenth()) + "," + (table.getDecimalDigits() != null && table.getDecimalDigits().length() > 0 ? table.getDecimalDigits():"4") + ")";
break;
default:
System.err.println("---- 表名:" + table.getTableName() + " 列名:" + table.getFiled() +" 类型:" + table.getFiledType() + " 出现异常!");
returnType = "VARCHAR2(" + table.getFiledLenth() + ")";
break;
}
return returnType;
}
private static String formateDefaultValue(String defaultValue) {
String returnValue = "";
if (defaultValue != null && defaultValue.length() > 0) {
if (defaultValue.equals("0000-00-00 00:00:00") || defaultValue.equals("CURRENT_TIMESTAMP")) {
returnValue = "DEFAULT sysdate" ;
}else {
returnValue = "DEFAULT '" + defaultValue + "'";
}
}
return returnValue;
}
private static String formateIsNull(boolean isNull) {
return isNull ? "NULL" : "NOT NULL";
}
private static Map<String, List<TableInfo>> getTableMap(DatabaseMetaData metaData) throws SQLException {
List<String> tableNames = new ArrayList<>();
ResultSet rs = null;
rs = metaData.getTables(null, null, null, new String[] { "TABLE" });
while(rs.next()) {
tableNames.add(rs.getString(3));
}
Map<String, List<TableInfo>> tableMap = new HashMap<String, List<TableInfo>>();
ArrayList<TableInfo> tableList = null;
for (String thisTableName : tableNames) {
tableList = new ArrayList<TableInfo>();
ResultSet tableInfo = metaData.getColumns(null,"%", thisTableName, "%");
while (tableInfo.next()){
tableList.add(
new TableInfo(
tableInfo.getString("TABLE_NAME"),
tableInfo.getString("COLUMN_NAME"),
tableInfo.getString("TYPE_NAME"),
tableInfo.getInt("COLUMN_SIZE"),
tableInfo.getString("DECIMAL_DIGITS"),
tableInfo.getString("COLUMN_DEF"),
tableInfo.getBoolean("IS_NULLABLE"),
tableInfo.getBoolean("IS_AUTOINCREMENT"),
false,
tableInfo.getString("REMARKS")
)
);
}
ResultSet pkInfo = metaData.getPrimaryKeys(null, "%", thisTableName);
while (pkInfo.next()){
for (TableInfo table : tableList) {
if (table.getFiled().equals(pkInfo.getString("COLUMN_NAME"))) {
table.setisPrimaryKey(true);
}
}
}
tableMap.put(thisTableName, tableList);
}
return tableMap;
}
}
class TableInfo{
private String tableName;
private String filed;
private String filedType;
private Integer filedLenth;
private String decimalDigits;
private String defaultValue;
private boolean isNull;
private boolean isAutoAdd;
private boolean isPrimaryKey;
private String remark;
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getFiled() {
return filed;
}
public void setFiled(String filed) {
this.filed = filed;
}
public String getFiledType() {
return filedType;
}
public void setFiledType(String filedType) {
this.filedType = filedType;
}
public Integer getFiledLenth() {
return filedLenth;
}
public void setFiledLenth(Integer filedLenth) {
this.filedLenth = filedLenth;
}
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
public boolean isNull() {
return isNull;
}
public void setIsNull(boolean isNull) {
this.isNull = isNull;
}
public boolean isAutoAdd() {
return isAutoAdd;
}
public void setIsAutoAdd(boolean isAutoAdd) {
this.isAutoAdd = isAutoAdd;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public boolean isPrimaryKey() {
return isPrimaryKey;
}
public void setisPrimaryKey(boolean isPrimaryKey) {
this.isPrimaryKey = isPrimaryKey;
}
public String getDecimalDigits() {
return decimalDigits;
}
public void setDecimalDigits(String decimalDigits) {
this.decimalDigits = decimalDigits;
}
public TableInfo(String tableName, String filed, String filedType, Integer filedLenth,String decimalDigits,
String defaultValue, boolean isNull,
boolean isAutoAdd, boolean isPrimaryKey,String remark) {
super();
this.tableName = tableName;
this.filed = filed;
this.filedType = filedType;
this.filedLenth = filedLenth;
this.decimalDigits = decimalDigits;
this.defaultValue = defaultValue;
this.isNull = isNull;
this.isAutoAdd = isAutoAdd;
this.isPrimaryKey = isPrimaryKey;
this.remark = remark;
}
}