SQL优化及多数据库支持分享(二)

「这是我参与11月更文挑战的第 10 天,活动详情查看:2021最后一次更文挑战

1、前言

​ 上一次,我们说到了DB2环境的搭建,本次我们来分享下,如何把oracle中的表结构及数据同步到db2与mariadb中。
​ 刚开始,我拿到这个需求后也是很懵,有点无从下手。项目小组长给了我一个介绍db2与oracle有哪些不同的博客,然后就让我自己搞了了。整个项目有300多张表,挨个手工替换建表语句肯定是不现实的。后面通过百度也了解到了,阿里开源的datax等框架,但是datax并不支持oracle到db2的迁移。后来还是通过google,找到了一款SQL语句转换工具,SQLines (这个是线上版的,同时也有安装包) 现在我们就可以通过java程序批量将表结构转换成db2下的SQL,然后再写一个小工具先查出来,再插入到db2中即可。(这里也去找了些开源项目,但大多都好久没有维护了,调试运行起来太麻烦,干脆就自己简单写了下)

2、同步表结构及数据

​ 在这里我是先,把所有的表结构SQL语句导出到本地,然后批量转换成对应的DB2的建表语句。同步数据这里,因为就是要求简单快速,就也没有使用mybatis这些,我是简单写了一个小工具,这里推荐大家使用下hutool的数据库操作工具类,使用起来很简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
java复制代码@Slf4j
public class ConvertSQLXML {

public static void main(String[] args) {
String pathPub = "D:\\data";
log.debug("加载SQL-INFO配置:" + pathPub);
List<String> paths = new ArrayList<String>();
getDependencyPath(paths, pathPub, (f, n) -> {
return n.endsWith("info.xml");
});
log.info("SQL:{}", paths);
paths.forEach(v -> {
try {
write(v);
} catch (IOException e) {
e.printStackTrace();
}
});

}

private static void write(String filePath) throws IOException {
//1、一行一行的读
File file = new File(filePath);
String outSrc = "C:\\data";
String outFileOraclePath = outSrc + File.separator + "oracle-" + file.getName();
String outFileMySQLPath = outSrc + File.separator + "mysql-" + file.getName();
String outFileDB2Path = outSrc + File.separator + "db2-" + file.getName();
File outFile = new File(outFileOraclePath);
File outFileMySQL = new File(outFileMySQLPath);
File outFileDB2 = new File(outFileDB2Path);
if (!outFile.exists()) {
outFile.createNewFile();//有路径才能创建文件
}
outFileMySQL.createNewFile();//有路径才能创建文件
outFileDB2.createNewFile();//有路径才能创建文件
BufferedReader reader = null;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(outFile, true));
reader = new BufferedReader(new FileReader(file));
String tempStr;
while ((tempStr = reader.readLine()) != null) {
if (StringUtils.isBlank(tempStr) || Pattern.matches(xml, tempStr) || Pattern.matches(DOCTYPE, tempStr)) {
continue;
}
if (Pattern.matches(sqlinfo, tempStr) || Pattern.matches(check, tempStr)
|| Pattern.matches(CDATA, tempStr) || Pattern.matches(sql, tempStr)
|| Pattern.matches(sp, tempStr)) {
writer.newLine();
continue;
}
writer.write(tempStr);
writer.newLine();
}
reader.close();
writer.flush();
writer.close();
convertOracleToOther(outFileOraclePath, outFileMySQLPath, "mysql");
convertOracleToOther(outFileOraclePath, outFileDB2Path, "db2");
} catch (IOException e) {
e.printStackTrace();
} finally {
reader.close();
writer.close();
}
}

private static void convertOracleToOther(String filePathSrc, String filePathOut, String targetType) {
//sqlines.exe -s=oracle -t=sql -in=script.sql
String cmd = "C:\\sqlines.exe";
try {
//执行exe cmd可以为字符串(exe存放路径)也可为数组,调用exe时需要传入参数时,可以传数组调用(参数有顺序要求)
new ProcessBuilder(cmd," -s=oracle"," -t=" + targetType, " -in=" + filePathSrc, " -out=" + filePathOut).start();
} catch (Exception e) {
e.printStackTrace();
}
}

private static void getDependencyPath(List<String> paths, String path, FilenameFilter filter){
File file =new File(path);
File[] files = file.listFiles();
String[] names = file.list();
if(names != null){
for(int i=0;i < names.length;i++){
if (filter.accept(null , names[i])) {
paths.add(path + File.separator + names[i]);
}
}
}
for (File a : files) {
if(a.isDirectory()){ //判断有子文件
getDependencyPath(paths, a.getAbsolutePath()+"\\", (f, n) -> {
return n.endsWith("info.xml");
});
}
}
}

}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%