詳解kettle之User Defined Java Class步驟(二),kettledefined
詳解User Defined Java Class步驟(二)
kettle中的“user defined java class”步驟,也稱UDJC步驟,從4.0版本就有,功能非常強大,無所不能;可以在其中寫任意代碼,卻不影響效率。本文將詳細介紹在不同情境中用樣本展示如果使用該步驟,由於內容非常多,便於閱讀方便,把內容分成三部分,請完整看完全部內容,範例程式碼在這裡下載.
如果沒有從第一部分開始,請訪問第一部分。
使用步驟參數(Step Parameter)
如果你寫了一段代碼,如果想讓帶更通用,步驟參數這時就能用到;在樣本中,我們提供一個Regex和一個欄位的名稱,該步驟檢查參數對應的欄位是否匹配Regex,如果是返回結果為1,反之為0。
代碼如下:
import java.util.regex.Pattern;
private Pattern p = null;
private FieldHelper fieldToTest = null;
private FieldHelper outputField = null;
public boolean processRow(StepMetaInterfacesmi, StepDataInterface sdi) throws KettleException
{
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
// prepare regex and field helpers
if (first){
first = false;
String regexString = getParameter("regex");
p = Pattern.compile(regexString);
fieldToTest = get(Fields.In, getParameter("test_field"));
outputField = get(Fields.Out, "result");
}
r= createOutputRow(r, data.outputRowMeta.size());
// Get the value from an input field
String test_value = fieldToTest.getString(r);
// test for match and write result
if (p.matcher(test_value).matches()){
outputField.setValue(r, Long.valueOf(1));
}
else{
outputField.setValue(r, Long.valueOf(0));
}
// Send the row on to the next step.
putRow(data.outputRowMeta, r);
return true;
}
getParameter()方法返回在ui介面中定義的參數對應值內容,當然參數的值也可能是kettle的變數。把變數作為參數是使用變數通常的做法。我們可以在步驟的xml代碼中手工搜尋到變數。
樣本的轉換名稱是:parameter.ktr.
訊息步驟(Info Steps)使用
有時需要合并多個輸入步驟,可能賦予不同的角色,就如流查詢步驟。訊息步驟用來提供查詢,其資料行不通過getRow()方法返回。在udjc步驟中非常容易使用。在udjc步驟的ui介面訊息步驟選項卡中定義,通過getRowsFrom()方法返回對應的值。
樣本轉換中使用訊息步驟接收一組Regex,用其測試主流資料中的一個欄位是否匹配,如果任何一個運算式匹配,結果欄位設定為1.如果沒有任何匹配,則結果為0,同時附加輸出匹配的運算式。
代碼如下:
import java.util.regex.Pattern;
import java.util.*;
private FieldHelper resultField = null;
private FieldHelper matchField = null;
private FieldHelper outputField = null;
private FieldHelper inputField = null;
private ArrayList patterns = newArrayList(20);
private ArrayList expressions = newArrayList(20);
public boolean processRow(StepMetaInterfacesmi, StepDataInterface sdi) throws KettleException
{
Object[] r = getRow();
if (r == null) {
setOutputDone();
return false;
}
// prepare regex and field helpers
if (first){
first = false;
// get the input and output fields
resultField = get(Fields.Out, "result");
matchField = get(Fields.Out, "matched_by");
inputField = get(Fields.In, "value");
// get all rows from the info stream andcompile the regex field to patterns
FieldHelper regexField = get(Fields.Info, "regex");
RowSet infoStream = findInfoRowSet("expressions");
Object[] infoRow = null;
while((infoRow = getRowFrom(infoStream)) != null){
String regexString = regexField.getString(infoRow);
expressions.add(regexString);
patterns.add(Pattern.compile(regexString));
}
}
// get the value of the field to check
String value = inputField.getString(r);
// check if any pattern matches
int matchFound = 0;
String matchExpression = null;
for(int i=0;i<patterns.size();i++){
if (((Pattern) patterns.get(i)).matcher(value).matches()){
matchFound = 1;
matchExpression = (String)expressions.get(i);
break;
}
}
// write result to stream
r= createOutputRow(r, data.outputRowMeta.size());
resultField.setValue(r, Long.valueOf(matchFound));
matchField.setValue(r, matchExpression);
// Send the row on to the next step.
putRow(data.outputRowMeta, r);
return true;
}
調用findInfoRowSet()方法,返回在udjc步驟的訊息步驟中定義的名稱對應的輸入步驟的整個行集內容。從行集內容中讀取某行與從主要資料流中去某行不同,通過調用getRowFrom(),並顯示指明那個行集。
樣本轉換的名稱為info_steps.ktr.
使用目標步驟(Target Steps)
使用udjc步驟有時可能需要指定行集流轉到不同的目標步驟。通過調用putRow()方法,並傳遞一個目標步驟作為參數。我們需要在udjc步驟的ui介面的目標步驟中定義所有可能的目標步驟,下面樣本中隨機分發行資料到不同弄的目標步驟。
findTargetRowSet()方法返回在ui介面中定義的目標步驟行集,並作為putRowto()方法的參數.樣本轉換的名稱為target_steps.ktr.
代碼如下:
import java.util.regex.Pattern;
import java.util.*;
private RowSet lowProbStream = null;
private RowSet highProbStream = null;
public boolean processRow(StepMetaInterfacesmi, StepDataInterface sdi) throws KettleException
{
Object[]r = getRow();
if(r == null) {
setOutputDone();
returnfalse;
}
//prepare regex and field helpers
if (first){
first = false;
lowProbStream= findTargetRowSet("low_probability");
highProbStream= findTargetRowSet("high_probability");
}
//Send the row on to the next step.
if(Math.random() < 0.35){
putRowTo(data.outputRowMeta, r,lowProbStream);
}
else{
putRowTo(data.outputRowMeta, r,highProbStream);
}
returntrue;
}
更多內容請查看第三部分;
問kettle怎使用User Defined Java Class這個控制項
String firstnameField;
String lastnameField;
String nameField;
public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
{
// 擷取輸入
//
Object[] r = getRow();
// 輸入為空白,直接false
//
if (r == null) {
setOutputDone();
return false;
}
// 處於效能考慮,parameter只查一次
//
if (first) {
firstnameField = getParameter("FIRSTNAME_FIELD");
lastnameField = getParameter("LASTNAME_FIELD");
nameField = getParameter("NAME_FIELD");
first=false;
}
// 用 createOutputRow() 來保證output的數組夠大,能夠裝下任何新的域
//
Object[] outputRow = createOutputRow(r, data.outputRowMeta.size());
String firstname = get(Fields.In, firstnameField).getString(r);
String lastname = get(Fields.In, lastnameField).getString(r);
// Set the value in the output field
//
String name = firstname+" "+lastname;
get(Fields.Out, nameField).setValue(outputRow, name);
// putRow will send the row on to the default output hop.
//
putRow(data.outputRowMeta, outputRow);
return true;
}
kettle java class怎把結果輸出到控制台
不是javaw運行,然後使用System.out.print 就可以輸出