1.环境准备
1.jdk 1.8
2.python 2.6.X(Python3不行 !!!)
3.Maven 3.X
下载DataX: http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz.
2.测试DataX
下载好的DataX是一个压缩包,解压就行,不要有中文路径
安装后Python,配置好环境变量(我安装的是2.6.4),cmd窗口,输入python,如下图
我的DataX路径如下
重点
datax文件夹里面有个bin文件夹,里面有个datax.py文件,记住他的位置,后面会用到的
datax里面还有个job文件夹,里面会有一个初始化的job.json文件,这个是文件里面的格式书写的有一定要求的,详细要求可以参考官网:https://github.com/alibaba/DataX/
cmd 输入 CHCP 65001 可以解决乱码问题
如果Python环境变量配置没问题就可以在cmd窗口输入
python datax.py的全路径 job.json的全路径
例如我的:
python D:\worksoft\datax\bin\datax.py D:\worksoft\datax\job\job.json
执行结果如下
到此为止,dataX的一个简单测试就完成了,注意cmd最后一段
至于json文件的书写格式,参考DataX官网https://github.com/alibaba/DataX/
3.在java环境下进行数据库的数据同步
思路:根据不同的数据库类型,生成不同的json格式的字符串,将json字符串写入job文件加下,通过java调用cmd执行python指令运行json脚本,完成数据同步
建立一个Springboot项目,将解压的解压的datax文件放到resource文件夹下
我的项目结构
java工具类如下(写的很随意,只写了Oracle和Mysql两个类型数据库)
package com.datax.test;
import java.io.*;
import java.util.List;
import java.util.UUID;
/**
* @description: dataX数据同步的工具类
* @author: Mr.Black
* @create: 2021-02-04 14:12
**/
public class DataXUtil {
public static void exeDatax(String jsonPath) throws IOException {
//获取datax.py文件的规范化绝对路径
File dataXFile = new File("src/main/resources/datax/bin/datax.py");
String dataXPath = dataXFile.getCanonicalPath();
File jsonFile = new File(jsonPath);
jsonPath = jsonFile.getCanonicalPath();
System.out.println("------------------start----------------------");
//name为文件json文件名
String command = "python " + dataXPath + " " + jsonPath;
System.out.println(command);
//通过调用cmd执行python执行
Process pr = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
try {
pr.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* @Author: Mr.Black
* @Description: 创建json文件中reader部分内容
* @DateTime: 14:36 2021/2/5
* @Params: [databaseType 数据类型, readerUsername 源数据库的用户名, readerPwd 源数据库的密码, querySql 查询sql, jdbcUrl 数据库连接url]
* @Return:
*/
public static String createReader(Integer databaseType, String readerUsername, String readerPwd, String querySql, String jdbcUrl) {
String readerName = "";
//数据库类型 (1-Oracle,2-MySql)
if (databaseType == 1) {
readerName = "oraclereader";
} else if (databaseType == 2) {
readerName = "mysqlreader";
} else {
throw new RuntimeException("不支持除Mysql 和 Oracle 外数据库类型!");
}
String readerJson = "{\n" +
" \"job\": {\n" +
" \"setting\": {\n" +
" \"speed\": {\n" +
" \"channel\":1\n" +
" }\n" +
" },\n" +
" \"content\": [\n" +
" {\n" +
" \"reader\": {\n" +
" \"name\": \"" + readerName + "\",\n" +
" \"parameter\": {\n" +
" \"username\": \"" + readerUsername + "\",\n" +
" \"password\": \"" + readerPwd + "\",\n" +
" \"connection\": [\n" +
" {\n" +
" \"querySql\": [\n" +
" \"" + querySql + "\"\n" +
" ],\n" +
" \"jdbcUrl\": [\n" +
" \"" + jdbcUrl + "\"\n" +
" ]\n" +
" }\n" +
" ]\n" +
" }\n" +
" },\n";
return readerJson;
}
/**
* @Author: Mr.Black
* @Description: 创建json文件中writer部分内容
* @DateTime: 14:41 2021/2/5
* @Params: [databaseType 数据库类型, writerUsername 目标库用户名, writerPwd 目标库密码, jdbcUrl 目标库连接URL, table 目标表, 指定字段 sourceFields]
* @Return:
*/
public static String createWriter(Integer databaseType, String writerUsername, String writerPwd, String jdbcUrl, String table, List<String> targetFields) {
String writerJson = "";
String writerName = "";
//数据库类型 (1-Oracle,2-MySql)
if (databaseType == 1) {
writerName = "oraclewriter";
} else if (databaseType == 2) {
writerName = "mysqlwriter";
} else {
throw new RuntimeException("不支持除Mysql 和 Oracle 外数据库类型!");
}
String writerJsonHead = " \"writer\": {\n" +
" \"name\": \"" + writerName + "\",\n" +
" \"parameter\": {\n" +
" \"username\": \"" + writerUsername + "\",\n" +
" \"password\": \"" + writerPwd + "\",\n" +
" \"column\": [\n";
for (int i = 0; i < targetFields.size(); i++) {
if (i == targetFields.size() - 1) {
writerJsonHead += " \"" + targetFields.get(i) + "\"";
} else {
writerJsonHead += " \"" + targetFields.get(i) + "\",";
}
}
String writerJsonFoot = " \n" +
" ],\n" +
" \"connection\": [\n" +
" {\n" +
" \"jdbcUrl\": \"" + jdbcUrl + "\",\n" +
" \"table\": [\n" +
" \"" + table + "\"\n" +
" ]\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
return writerJson = writerJsonHead + writerJsonFoot;
}
/**
* @Author: Mr.Black
* @Description: 创建datax执行的JSON脚本
* @DateTime: 15:00 2021/2/5
* @Params: [json]
* @Return: JSON文件名全路名
*/
public static String createJobJson(String json) {
String jsonPath = "src/main/resources/datax/job/" + UUID.randomUUID().toString().replace("-", "")+".json";
//将json写入文件中
byte[] jsonBytes = json.getBytes();
try {
FileOutputStream fos = new FileOutputStream(jsonPath);
fos.write(jsonBytes);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return jsonPath;
}
}
测试类
package com.datax.test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @program: test
* @description:
* @author: Mr.Black
* @create: 2021-02-04 17:23
**/
public class TestUtil {
public static void main(String[] args) throws IOException {
//数据库类型 (1-Oracle,2-MySql)
String reader = DataXUtil.createReader(数据库类型, "用户名", "d密码1", "查询数据的SQL", "数据库连接URL");
List<String> list = new ArrayList<>();
list.add("字段1");
list.add("字段2");
list.add("字段3");
list.add("字段4");
list.add("字段5");
......
//reader中的查询字段顺序要与list中相对应,包括数据类型
//数据库类型 (1-Oracle,2-MySql)
String writer = DataXUtil.createWriter(数据库类型, "用户名", "密码", "URL",list);
String jsonPath = DataXUtil.createJobJson(reader + writer);
System.out.println(jsonPath);
DataXUtil.exeDatax(jsonPath);
}
}
运行结果
json里面的书写格式一定要详细阅读官方文档
json里面的书写格式一定要详细阅读官方文档
json里面的书写格式一定要详细阅读官方文档
https://github.com/alibaba/DataX/