table和API
table和API基本示例
引入的依赖
planner计划。计划器,这是tableAPI中最主要的部分,提供一个运行时的环境。基于运行时的环境解析流式处理程序,生成一个表的执行计划,2.12是Scala的版本。1.10是flink的版本。
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_2.12</artifactId>
<version>1.10.1</version>
</dependency>
bridge桥接器,语言的转换工具。2.12是Scala的版本。1.10是flink的版本。下面是Scala语言的转换器,如果用Java语言就用Java语言的转换器。
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-api-scala-bridge_2.12</artifactId>
<version>1.10.1</version>
</dependency>
代码基本步骤
1、创建流式处理环境,获取到数据,将数据转换成一定的格式的流数据。
2、创建表的处理环境,表处理环境从数据流中获取流数据,作为一张表。
3、Table的方式: 在这张表上进行做一些方法操作,得到最终想要的表。
4、sql的方式:在环境中注册这张表,然后写一个SQL作为一个字符串,然后进行执行。
需要注意的地方:
1、表环境的创建是基于流环境的创建的。流环境创建的时候,直接是流执行环境.获取执行环境。而表环境创建的时候,表执行环境.创建(流环境变量)。
2、从流中获取的数据,创建的表,并没有在表环境中注册管理,因此需要注册创建一个视图。
3、print打印的时候,表转换成流的话可以使用print这个方法。
代码演示
package com.atguigu.apitest
import org.apache.flink.streaming.api.scala._
import org.apache.flink.table.api.Table
// scala语言用这个,Java对应的改成Java
import org.apache.flink.table.api.scala._
// import org.apache.flink.table.api.java.StreamTableEnvironment
case class SensorReadingTabletest (id :String , timestamp: Long ,tempreture:Double)
object tabletest {
def main(args: Array[String]): Unit = {
// 定义流式处理环境。
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
// 从文件中读取数据。
val inpath = "D:\\code_put\\flink_tuturial\\src\\main\\resources\\Sensor.txt"
val inputStream: DataStream[String] = env.readTextFile(inpath)
val dataStream: DataStream[SensorReadingTabletest] = inputStream.map(data => {
val strings = data.split(",")
SensorReadingTabletest(strings(0), strings(1).toLong, strings(2).toDouble) //方法的返回值
})
//创建表的执行环境。
// 底层是流处理,基于流处理来创建当前的表环境。
// scala语言用这个,Java对应的改成Java,注意导包。
//import org.apache.flink.table.api.scala._
val tabEnv: StreamTableEnvironment = StreamTableEnvironment.create(env)
//基于流创建一张表
// --也就是流中的数据放入到表中,从流中拿来数据作为一张表
// dataTable现在是一张表,想象成SQL语句中的表。
val dataTable: Table = tabEnv.fromDataStream(dataStream)
// -- 用table实现,这种就是类比于在 SQLyoug中进行手动选择,最后展示出来什么样的效果。
// 调用table API ,通过sql之后形成的新的表。
val resultTable = dataTable
.select("id,tempreture") //相当于SQL中的select,要选那些字段。
.filter("id ='sensor_1'") //过滤条件,相当于SQL中的where。
//转换成流的话,就是可以进行print输出。
resultTable.toAppendStream[(String,Double)].print("tab")
// 如果用SQL写的话,还是有一点点的麻烦。
// 1、对dataTable进行注册,因为dataTable就是直接从流中直接转换过来的。
// 2、dataTable这张表是Table数据类型,并没有在当前的表环境中有catalog,并没有管理起来。
// 3、如果想写SQL的话,必须是在目录里面有注册的,才可以直接在SQL里面直接调用这个表名字。
tabEnv.createTemporaryView("dataTable",dataTable) //第一个是注册的视图名字,第二个是对哪个表进行注册。
// 然后在SQL中可以直接用这个视图的名字。
val sql :String ="select id,tempreture from dataTable where id = 'sensor_1'"
//基于环境,进行执行SQL。
val resultSqlTable = tabEnv.sqlQuery(sql)
//转换成流的话,就是可以进行print输出。
resultSqlTable.toAppendStream[(String, Double)].print("sql")
env.execute()
}
}
基本程序结构
这里的connect是连接外部的数据系统,文件,kafka…。读入,写出。
这里是直接从外部系统读取数据,就可以直接在表环境中注册出来,注册的是表,不是视图。如果是从流中读取数据,那么就是注册的是视图。
1、 tableApi要用的话,必须先得到table数据类型,那怎么得到Table数据类型呢?用from方法,把当前表环境注册好的表读出来,得到一个Table类型的表。
2、SQL的话,直接用环境注册好的那张表。
注意from后面加双引号。