GitHub
https://github.com/SmallScorpion/flink-tutorial.git
函数(Functions)
用户自定义函数(UDF)
- 用户定义函数(User-defined Functions,UDF)是一个重要的特性,它们显著地扩展了查询的表达能力,一些系统内置函数无法解决的需求,我们可以用UDF来自定义实现。
- 在大多数情况下,用户定义的函数必须先注册,然后才能在查询中使用
- 函数通过调用 registerFunction()方法在 TableEnvironment 中注册。当用户定义的函数被注册时,它被插入到 TableEnvironment 的函数目录中,这样Table API 或 SQL 解析器就可以识别并正确地解释它
标量函数(Scalar Functions)
- 用户定义的标量函数,可以将0、1或多个标量值,映射到新的标量值
- 为了定义标量函数,必须在 org.apache.flink.table.functions 中扩展基类Scalar Function,并实现(一个或多个)求值(eval)方法
- 标量函数的行为由求值方法决定,求值方法必须公开声明并命名为 eval
import java.sql.Timestamp
import com.atguigu.bean.SensorReading
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.table.api.Table
import org.apache.flink.table.api.scala._
import org.apache.flink.table.functions.ScalarFunction
import org.apache.flink.types.Row
object ScalarFunctionTest {
def main(args: Array[String]): Unit = {
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
// 开启事件时间语义
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
// 创建表环境
val tableEnv: StreamTableEnvironment = StreamTableEnvironment.create(env)
val inputDStream: DataStream[String] = env.readTextFile("D:\\MyWork\\WorkSpaceIDEA\\flink-tutorial\\src\\main\\resources\\SensorReading.txt")
val dataDStream: DataStream[SensorReading] = inputDStream.map(
data => {
val dataArray: Array[String] = data.split(",")
SensorReading(dataArray(0), dataArray(1).toLong, dataArray(2).toDouble)
})
.assignTimestampsAndWatermarks( new BoundedOutOfOrdernessTimestampExtractor[SensorReading]
( Time.seconds(1) ) {
override def extractTimestamp(element: SensorReading): Long = element.timestamp * 1000L
} )
// 用proctime定义处理时间
val dataTable: Table = tableEnv
.fromDataStream(dataDStream, 'id, 'temperature, 'timestamp.rowtime as 'ts)
// 使用自定义的hash函数,求id的哈希值
val myHashCode = MyHashCode(1.23)
// 查询 Table API 方式
val resultTable: Table = dataTable
.select('id, 'ts, myHashCode('id)) // 查询id和temperature字段
// SQL调用方式,首先要注册表
tableEnv.createTemporaryView("dataTable", dataTable)
// 注册函数
tableEnv.registerFunction("myHashCode", myHashCode)
val resultSqlTable: Table = tableEnv.sqlQuery(
"""
|select id, ts, myHashCode(id)
|from dataTable
|""".stripMargin)
// 测试输出
resultTable.toAppendStream[ Row ].print( "scalar" )
resultSqlTable.toAppendStream[ Row ].pr