flink UDF/UDAF/UDTF详解

总结出UDF/UDAF/UDTF三种函数的写法,并配以代码和注释说明。

一、UDF
介绍:自定义标量函数(User Defined Scalar Function),一行输入,一行输出。

import org.apache.flink.table.functions.ScalarFunction;

/**
 *   功能:字符串转小写
 *   注册函数:create function DemoUDF as 'packagename.DemoUDF';
 *   使用案例:select DemoUDF('Abc')
 */
public class DemoUDF extends ScalarFunction {

    public DemoUDF() {}

    public String eval(String str) {
        return str.toLowerCase();
    }
}

二、UDAF
介绍:自定义聚合函数,多行输入,一行输出。

import org.apache.flink.table.functions.AggregateFunction;

/**
 -   功能:求和
 -   注册函数:create function DemoUDAF as 'packagename.DemoUDAF';
 -   使用案例:
         select student_id,DemoUDAF(score)
         from tablename
         group by student_id
 */
// AggregateFunction<聚合的最终结果类型,聚合期间的中间结果类型>
public class DemoUDAF extends AggregateFunction<Long, DemoUDAF.SumAccumulator> {

    //定义一个累加器,存放聚合的中间结果
    public static class SumAccumulator{
        public long sumPrice;
    }

    //初始化累加器
    @Override
    public SumAccumulator createAccumulator() {
        SumAccumulator sumAccumulator = new SumAccumulator();
        sumAccumulator.sumPrice=0;
        return sumAccumulator;
    }

    //根据输入,更新累加器
    @Override
    public void accumulate(SumAccumulator accumulator,Long input){
        accumulator.sumPrice += input;
    }

    //返回聚合的最终结果
    @Override
    public Long getValue(SumAccumulator accumulator) {
        return accumulator.sumPrice;
    }
}

三、UDTF
介绍:自定义<表函数>,这类函数是作用于表,而不是字段。
UDTF可以细分为3类:

  • 一行输入,多行输出
  • 一列输入,多列输出
  • 一行输入,多行多列输出

UDTF之一行输入,多行输出

import org.apache.flink.table.annotation.DataTypeHint;
import org.apache.flink.table.annotation.FunctionHint;
import org.apache.flink.table.functions.TableFunction;
import org.apache.flink.types.Row;


/**
 *   功能:根据指定的分隔符,将一行变成多行
 *   注册函数:create function DemoRowMore as 'packagename.DemoRowMore';
 *   使用案例:
         select *,word
         from tablename,LATERAL TABLE(DemoRowMore(fieldname,',')) as T(word)
 */

public class DemoRowMore extends TableFunction<Row> {

    public DemoRowMore() {
    }

    // 使用注解指定输出数据的名称和类型
    // 没有返回值,使用collect收集数据,可以收集多次
    @FunctionHint(output = @DataTypeHint("ROW<word STRING>"))
    public void eval(String data,String split){
        String[] arr = data.split(split);
        for (String s : arr) {
            collect(Row.of(s));
        }
    }
}
数据样例:
a,b,c
d,e

Flink SQL>
select word
from tablename,LATERAL TABLE(DemoRowMore(fieldname,',')) as T(word);

Flink SQL>
a
b
c
d
e

UDTF之一列输入,多列输出

import org.apache.flink.table.annotation.DataTypeHint;
import org.apache.flink.table.annotation.FunctionHint;
import org.apache.flink.table.functions.TableFunction;
import org.apache.flink.types.Row;

/**
 *   功能:根据给定的分隔符,将一列变成两列
 *   注册函数:create function DemoColumnMore as 'packagename.DemoColumnMore';
 *   使用案例:
        select *,name,city
        from tablename,LATERAL TABLE(DemoColumnMore(fieldname,',')) as T(name,city)
 */
public class DemoColumnMore extends TableFunction<Row> {

    public DemoColumnMore() {
    }

    // 使用注解指定输出数据的名称和类型
    @FunctionHint(output = @DataTypeHint("ROW<name STRING,city STRING>"))
    public void eval(String data, String split){
        String[] arr = data.split(split);
        Row row = new Row(2);
        row.setField(0,arr[0]);
        row.setField(1,arr[1]);
        collect(row);
    }
}
数据样例:
'张三,上海'

Flink SQL>
select name,city
from tablename,LATERAL TABLE(DemoColumnMore(fieldname,',')) as T(name,city)

Flink SQL>
'张三','上海'

创作不易,希望对你有所帮助!

一健三联就是对我最大的鼓励,笔芯~

交流加微wex997520707~

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值