kettle 复制和分发记录
如下图模型,一个表输入,两个表输出,那么这个表的数据是复制到两个表输出还是分发给两个表输出?
在连接线的时候会有下图提示, 提示你选择复制还是分发,分发也有解释轮流接收记录,也就是两表输出一个接收一半,另一个接收一半。
那么代码呢?依旧是上次mysql交换到hive的那个代码,稍微改一改,只不过不是两个表输出,而是一个是TableOutputMeta,一个是RowsToResultMeta(复制到结果集)
上一次我们是把tableinput和tableout关联起来,如下图,这样表输入关联到表输出。
//将步骤和上一步关联起来
transMeta.addTransHop(new TransHopMeta(tableInputStepMeta, tableOutputStep));
如果同时要把表输入关联到结果集,那么加上下面这个代码,
//复制记录到结果
RowsToResultMeta rowsToResultMeta = new RowsToResultMeta();
String rowsToResultMetaPluginId = registry.getPluginId(StepPluginType.class, rowsToResultMeta);
//添加步骤到转换中
StepMeta rowsToResultStep = new StepMeta(rowsToResultMetaPluginId, "rowsToResult", (StepMetaInterface)rowsToResultMeta);
transMeta.addStep(rowsToResultStep);
//添加hop把两个步骤关联起来
transMeta.addTransHop(new TransHopMeta(tableInputStepMeta, rowsToResultStep));
可是这样的话,是分发,不是复制。
如果想复制表输入到两个输出,那么就需要添加如下代码,设置为false即可。
tableInputStepMeta.setDistributes(false);
运行后如下图所示,原本表里有2条数据,这样就复制给了表输出和结果集,而不是分发。
完整代码如下所示
/**
* mysql到hive之间的交换
* @throws KettleException
*/
@Test
public void exchangeMySQL2Hive() throws KettleException{
//源数据库连接
String mysqL_src = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<connection>" +
"<name>mysqL_src</name>" +
"<server>192.168.10.64</server>" +
"<type>MYSQL</type>" +
"<access>Native</access>" +
"<database>test</database>" +
"<port>3306</port>" +
"<username>root</username>" +
"<password>root</password>" +
"</connection>";
//目标数据库连接
String hive_dest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<connection>" +
"<name>hive_dest</name>" +
"<server>192.168.10.212</server>" +
"<type>HIVE2</type>" +
"<access>Native</access>" +
"<database>ntzw_dev_64</database>" +
"<port>10000</port>" +
"<username>hadoop</username>" +
"<password>hadoop</password>" +
"</connection>";
DatabaseMeta srcDatabaseMeta = new DatabaseMeta(mysqL_src);
DatabaseMeta destDatabaseMeta = new DatabaseMeta(hive_dest);
//创建转换元信息
TransMeta transMeta = new TransMeta();
transMeta.setName("mysql到hive之间的交换");
//设置源和目标
transMeta.addDatabase(srcDatabaseMeta);
transMeta.addDatabase(destDatabaseMeta);
/*
* 创建 表输入->表输出
* 同时将两个步骤连接起来
*/
PluginRegistry registry = PluginRegistry.getInstance();
TableInputMeta tableInputMeta = new TableInputMeta();
String tableInputPluginId = registry.getPluginId(StepPluginType.class,
tableInputMeta);
tableInputMeta.setDatabaseMeta(srcDatabaseMeta);
//设置查询条件
String selectSql = "select id ,name from user_info_src";
tableInputMeta.setSQL(selectSql);
StepMeta tableInputStepMeta = new StepMeta(tableInputPluginId,
"tableInput", (StepMetaInterface) tableInputMeta);
tableInputStepMeta.setDistributes(false);
transMeta.addStep(tableInputStepMeta);
TableOutputMeta tableOutputMeta = new TableOutputMeta();
tableOutputMeta.setDatabaseMeta(destDatabaseMeta);
//设置目标表的 schema和表名
tableOutputMeta.setSchemaName(null);
tableOutputMeta.setTablename("user_info_dest");
String tableOutputPluginId = registry.getPluginId(StepPluginType.class, tableOutputMeta);
StepMeta tableOutputStep = new StepMeta(tableOutputPluginId, "tableOutput" , (StepMetaInterface) tableOutputMeta);
//将步骤添加进去
transMeta.addStep(tableOutputStep);
//将步骤和上一步关联起来
transMeta.addTransHop(new TransHopMeta(tableInputStepMeta, tableOutputStep));
//复制记录到结果
RowsToResultMeta rowsToResultMeta = new RowsToResultMeta();
String rowsToResultMetaPluginId = registry.getPluginId(StepPluginType.class, rowsToResultMeta);
//添加步骤到转换中
StepMeta rowsToResultStep = new StepMeta(rowsToResultMetaPluginId, "rowsToResult", (StepMetaInterface)rowsToResultMeta);
transMeta.addStep(rowsToResultStep);
//添加hop把两个步骤关联起来
transMeta.addTransHop(new TransHopMeta(tableInputStepMeta, rowsToResultStep));
Trans trans = new Trans(transMeta);
//执行转换
trans.execute(null);
//等待完成
trans.waitUntilFinished();
if (trans.getErrors() > 0) {
System.out.println("交换出错.");
return;
}else{
Result result = trans.getResult();
List<RowMetaAndData> rows = result.getRows(); //获取数据
for (RowMetaAndData row : rows) {
RowMetaInterface rowMeta = row.getRowMeta(); //获取列的元数据信息
String[] fieldNames = rowMeta.getFieldNames();
Object[] datas = row.getData();
for (int i = 0; i < fieldNames.length; i++) {
System.out.println(fieldNames[i]+"="+datas[i]);
}
}
}
}