发布时间:2024-04-01 09:01
整体项目为数据统计类系统,源数据库为oracle,考虑到法律风险和成本控制,需要落库为mysql,并实现定时更新功能。
多的不说,具体看操作过程。
这个过程中,找了很多种实现方式和工具,目前能基本实现项目的需求,不过便利程度上还是需要斟酌。
1)navicat15(这个版本能控制单次执行插入语句的数量,分批执行)
2)kettle(开源的etl工具)
3)结合些部分自己处理的工具和代码
首先用navicat的数据传输功能进行异构数据库的传输
1、先配置oracle和mysql数据库的连接
mysql比较简单,oracle的话主要要下载对应操作系统(一般是x64)的oracle client客户端,把oci.dll这个文件添加进来,选择工具—选项。
好了后,选择数据传输,选择连接,这里也可以选择导出为文件(sql文件)
然后点击选项,这里有几个地方需要的
1)创建表去掉索引,外键这些
2)使用扩展插入,这样速度会比较快(但是如果全量插入,数据量比较大的话会有问题),这里我一开始操作,数据量几十万的表,一次性扩展插入,导致内存溢出,一开始是8g内存,后来加了内存到32g,就没出问题了。这里选择高级,单次1000次(这个数值可以改),但是如果表比较多的话一个个改也是个麻烦事,so后来发现有个配置文件,可以手动批量修改好,看图
主要的不同也就是如下框出来的地方,我这里用excel和程序进行批量处理的
先查出oracle所有表名
SELECT table_name from all_tab_comments
where table_type=\'TABLE\'
and owner=\'CSRC\'
order by table_name
=CONCATENATE(\"\"\"\"&A1&\"\"\"\",\",\")
,在用java程序处理这些表名,生成列表内容,复制s.ndtfpremium
的头部和尾部,形成这些表配置文件
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* @Description: TODO
* @author: wangchi
* @date: 2022年05月31日 15:17
*/
public class Test1 {
public static void main(String[] args) throws IOException {
String[] s1 = {
\"RMI_LOG_201804\",
\"RMI_LOG_201805\"
};
fun1(s1); //拼接字符串
}
public static void fun1(String[] s1) throws IOException {
StringBuilder s2=new StringBuilder();
for (int i = 0; i <s1.length ; i++) {
String s3=\"{\\n\" +
\" \\\"Name\\\": \\\"\";
String s4=\"\\\",\\n\" +
\" \\\"ObjectType\\\": \\\"TableNormal_ORA\\\",\\n\" +
\" \\\"Advanced\\\": {\\n\" +
\" \\\"TargetTableName\\\": \\\"\";
String s5=\"\\\",\\n\" +
\" \\\"UseAllFields\\\": true,\\n\" +
\" \\\"FieldMappings\\\": [],\\n\" +
\" \\\"UseAllRows\\\": true,\\n\" +
\" \\\"EnableNumberOfRowsPerBatch\\\": true,\\n\" +
\" \\\"NumberOfRowsPerBatch\\\": 100,\\n\" +
\" \\\"RecordsetConditions\\\": [],\\n\" +
\" \\\"UseTransactionForEachRecordset\\\": true\\n\" +
\" }\\n\" +
\" },\";
s2.append(s3);
s2.append(s1[i]);
s2.append(s4);
s2.append(s1[i]);
s2.append(s5);
s2.append(\"\\n\");
}
System.out.println(s2); // 输出拼接后的结果
fileWriterMethod(\"D:\\\\bigdata_work\\\\javaWorkspace\\\\jeecgboot\\\\批量拼接字符串_navicat配置\\\\src\\\\file/s.ndtfpremium\",s2.toString()); //将文件流重写到路径文件中
}
public static void fileWriterMethod(String filepath, String content) throws IOException {
// 文件不存在则新建
File file = new File(filepath);
if (!file.exists()) {
file.createNewFile();
}
try (FileWriter fileWriter = new FileWriter(filepath)) {
fileWriter.append(content);
}
}
}
点击下一步开始就ok了,不过在实际运行的过程中,发现仍然会导致内存很高,跑了一段时间后,我想可能还是跟navicat本身的机制有关,可以分多次处理(比如500张表分50张表跑一次批),这样可能会好点
基本的表结构和数据都能正常拿到,只不过部分类型的字段会不太美观,比如主键的number类型转化,但是也不影响开发使用就是
目前已有的条件下,只做到这样的异构数据批量同步,大家有好的实现思路和方法,也欢迎一起探讨!
后续会继续看下其他方式的更新