建表语句插入的位置
自动建立Writer端的表,下面是一个简单的实现没有考虑可扩展性。具体代码加入到mysqlwriter这个模块即可。自动建表应该在哪调用呢,我选择了MysqlWriter#Job#init这个方法。
// MysqlWriter#Job#init
public void init() {
this.originalConfig = super.getPluginJobConf();
this.commonRdbmsWriterJob = new CommonRdbmsWriter.Job(DATABASE_TYPE);
// 建表
MysqlAutoCreateTable.createTable(getPeerPluginJobConf(), originalConfig);
// init中会用到Writer端的表,所以在这之前必须先建好表
this.commonRdbmsWriterJob.init(this.originalConfig);
}
建表的功能实现
一对一的导入;
多对一的导入,如果Reader端是多个table或者多个querySql,只会取第一个table或者querySql来进行建表所以如果是多对一需要保证Reader端多个表导入到Writer端的字段相同,或者将最多的字段放在第一个table或者querySql中;
需要配置:writer.name.parameter.autoCreateTable = true,默认为false。
代码:com.alibaba.datax.plugin.writer.mysqlwriter.MysqlAutoCreateTable.java
class MysqlAutoCreateTable {
private static final Logger LOG = LoggerFactory
.getLogger(MysqlAutoCreateTable.class);
private static String AUTO_CREATE_TABLE = "autoCreateTable";
private static final Pattern CREATE_TABLE_PATTERN = Pattern
.compile("\\s*[c,C][r,R][e,E][a,A][t,T][e,E]\\s+[t,T][a,A][b,B][l,L][e,E]\\s+(`?\\w+`?)\\s+");
private static final Pattern SELECT_PATTERN = Pattern
.compile("[f,F][r,R][o,O][m,M]\\s+(`?\\w+`?)");
static void createTable(Configuration readerConfiguration, Configuration writerConfiguration) {
// 首先判断标志位,如果为false直接返回了
if (!writerConfiguration.getBool(AUTO_CREATE_TABLE, false))
return;
List connections = writerConfiguration.getList(Constant.CONN_MARK,
Object.class);
// 确定目的端表的数目
int tableNum = 0;
for (int i = 0, len = connections.size(); i < len; i++) {
Configuration connConf = Configuration.from(connections.get(i).toString());
String jdbcUrl = connConf.getString(Key.JDBC_URL);
if (StringUtils.isBlank(jdbcUrl)) {
throw DataXException.as