背景
flink本身給我們提供了大量的內置函數,已經能滿足我們絕大部分的需求,但是如果確實是碰到了一些特殊的場景,無法滿足我們的需求的時候,我們可以自定義函數來解決,今天我們主要講一下最簡單的自定義函數-ScalarFunction。
標量函數的入參可以是0個、1個或者多個值,然後返回值是一個值。
實現標量函數需要繼承抽象類ScalarFunction,然後定一個名稱爲eval且爲public類型的函數。
實例講解
定義函數
定義標量函數有多重方式,我們下面來簡單的看下:
/**
* 接受兩個int類型的參數,然後返回計算的sum值
*/
public static class SumFunction extends ScalarFunction{
public Integer eval(Integer a, Integer b){
return a + b;
}
}
/**
* 接收非空的int或者boolean類型
*/
public static class StringifyFunction extends ScalarFunction{
public String eval(int i){
return String.valueOf(i);
}
public String eval(boolean b){
return String.valueOf(b);
}
}
/**
*接收非空的int或者boolean類型,通過註解方式實現,flink 1.11版本後支持
*/
@FunctionHint(input = [@DataTypeHint("INT")])
@FunctionHint(input = [@DataTypeHint("BOOLEAN")])
public static class StringifyFunction extends ScalarFunction {
public String eval(Object o) {
return o.toString();
}
}
/**
* 接收任何類型的值,然後把它們轉成string
*/
public static class StringifyFunction1 extends ScalarFunction{
public String eval(@DataTypeHint(inputGroup = InputGroup.ANY) Object o){
return o.toString();
}
}
通過程序註冊函數
//通過程序的方式來註冊函數
SumFunction sumFunction = new SumFunction();
tableEnv.registerFunction("mysum", sumFunction);
Table table1 = tableEnv.sqlQuery("select mysum(1,2)");
tableEnv.toAppendStream(table1, Row.class).print();
通過sql註冊函數
//通過sql的方式來註冊函數
String className = SumFunction.class.getName();
String sql = "create temporary function default_catalog.default_database.mysum1" +
" as '" + className + "'";
tableEnv.sqlUpdate(sql);
Table table2 = tableEnv.sqlQuery("select mysum1(3,4)");
tableEnv.toAppendStream(table2, Row.class).print();
之後我們可以通過StreamTableEnvironment類的listFunctions方法列出來所有的函數來看下我們自定義的函數是否在其中.
//列出來所有的函數,看是否包含我們定義的函數
String[] functions = tableEnv.listFunctions();
Stream.of(functions).filter(f->f.startsWith("mysum")).forEach(System.out::println);
最後如果自定義的jar和主程序不在一個jar包,通過命令行提交任務的時候,記得通過參數–classpath(簡寫-C)將包含自定義函數的jar添加到classpath裏。
今天的這個比較簡單,就不多說了,完整的代碼請參考
https://github.com/zhangjun0x01/bigdata-examples/blob/master/flink/src/main/java/sql/function/CustomScalarFunction.java
更多精彩內容,歡迎關注我的公衆號【大數據技術與應用實戰】,一起成長