ストリーミングクエリの場合、テーブルと外部コネクタ間の変換方法を宣言する必要があります。
外部システムと交換されるメッセージタイプは、更新モデルによって指定されます。出力ターゲットに応じて、次の3つのタイプを使用できます。たとえば、ファイルに出力する場合、更新および撤回モードを使用することはできません。わからないため、追加することしかできませんが、mysqlに変更する場合は、
- 追加モード(追加)-ファイルシステム
は、挿入操作でのみ追加モードテーブルをサポートし、外部コネクタとの挿入メッセージの交換のみを行います。 - 撤回モード(撤回)-最初に削除してから挿入し、更新操作
テーブルと外部コネクタの交換を実現します。追加(追加)および撤回(撤回)メッセージ。
挿入操作(挿入)は追加メッセージとしてエンコードされ、削除(削除)は撤回メッセージとしてエンコードされます。更新(更新)コードは、前の撤回と次の追加メッセージです - 更新挿入モード(アップサート)
更新と挿入の両方がアップサートメッセージとしてエンコードされ、削除は削除メッセージとしてエンコードされます
栗1-ファイルから読み取り、一連の操作を実行し、別のファイルに書き込みます
/**
*
* @author mafei
* @date 2020/11/22
*/
package com.mafei.apitest.tabletest
import org.apache.flink.streaming.api.scala._
import org.apache.flink.table.api.DataTypes
import org.apache.flink.table.api.scala._
import org.apache.flink.table.descriptors.{Csv, FileSystem, Schema}
object FileOutputTest {
def main(args: Array[String]): Unit = {
//1 、创建环境
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
val tableEnv = StreamTableEnvironment.create(env)
//2、读取文件
val filePath = "/opt/java2020_study/maven/flink1/src/main/resources/sensor.txt"
tableEnv.connect(new FileSystem().path(filePath))
.withFormat(new Csv()) //因为txt里头是以,分割的跟csv一样,所以可以用oldCsv
.withSchema(new Schema() //这个表结构要跟你txt中的内容对的上
.field("id", DataTypes.STRING())
.field("timestamp", DataTypes.BIGINT())
.field("temper", DataTypes.DOUBLE())
).createTemporaryTable("inputTable")
val sensorTable = tableEnv.from("inputTable")
//做简单转换
val simpleTramsformTable = sensorTable
.select("id,temper")
.filter("id='sensor1'")
//聚合转换
val aggTable = sensorTable
.groupBy('id)
.select('id, 'id.count as 'count)
//直接打印输出效果:
simpleTramsformTable.toAppendStream[(String, Double)].print("simpleTramsformTable: ")
//聚合的结果就不能用toAppendStream 因为他实现的是后面再来一条数据,表中就会增加一条,但是聚合的不是,是要更新之前的结果
aggTable.toRetractStream[(String, Long)].print("aggTable")
/**
* 输出的效果:
* aggTable> (true,(sensor1,1))
* simpleTramsformTable: > (sensor1,1.0)
* aggTable> (true,(sensor2,1))
* aggTable> (true,(sensor3,1))
* aggTable> (true,(sensor4,1))
* aggTable> (false,(sensor4,1)) //false代表重新计算了
* aggTable> (true,(sensor4,2))
* aggTable> (false,(sensor4,2))
* aggTable> (true,(sensor4,3))
*/
// 输出到文件中
val outputPath = "/opt/java2020_study/maven/flink1/src/main/resources/output.txt"
tableEnv.connect(new FileSystem().path(outputPath))
.withFormat(new Csv())
.withSchema(
new Schema()
.field("id", DataTypes.STRING())
.field("temper", DataTypes.DOUBLE())
)
.createTemporaryTable("outputTable")
simpleTramsformTable.insertInto("outputTable")
env.execute("file ouput")
}
}
コード構造と操作効果
カクファのあるトピックから読み、別のトピックに書き込む2番目の栗
/**
*
* @author mafei
* @date 2020/11/23
*/
package com.mafei.apitest.tabletest
import org.apache.flink.streaming.api.scala._
import org.apache.flink.table.api.DataTypes
import org.apache.flink.table.api.scala._
import org.apache.flink.table.descriptors.{Csv, Kafka, Schema}
object KafkaOutputTest {
def main(args: Array[String]): Unit = {
//1 、创建环境
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
val tableEnv = StreamTableEnvironment.create(env)
//2、从kafka中读取数据
tableEnv.connect(
new Kafka()
.version("0.11")
.topic("sourceTopic")
.startFromLatest()
.property("zookeeper.connect", "localhost:2181")
.property("bootstrap.servers", "localhost:9092")
).withFormat(new Csv())
.withSchema(new Schema() // 这个表结构要跟你kafka中的内容对的上
.field("id", DataTypes.STRING())
.field("timestamp", DataTypes.BIGINT())
.field("temperature", DataTypes.DOUBLE())
)
.createTemporaryTable("kafkaInputTable")
val sensorTable = tableEnv.from("kafkaInputTable")
//做简单转换
val simpleTramsformTable = sensorTable
.select("id,temperature")
.filter("id='sensor1'")
tableEnv.connect(
new Kafka()
.version("0.11")
.topic("sinkTopic")
.startFromLatest()
.property("zookeeper.connect", "localhost:2181")
.property("bootstrap.servers", "localhost:9092")
).withFormat(new Csv())
.withSchema(new Schema() //这个表结构要跟你kafka中的内容对的上
.field("id", DataTypes.STRING())
.field("temper", DataTypes.DOUBLE())
)
.createTemporaryTable("kafkaOutputTable")
simpleTramsformTable.insertInto("kafkaOutputTable")
env.execute("kafka sink test by table api")
}
}
このとき、2つのウィンドウを開くことができます。1つのウィンドウはトピック「sourceTopic」に書き込まれ、Flinkプログラムはこのトピックから読み取り、トピック「sinkTopic」に書き込み、コンシューマーコマンドラインを起動してこのトピックを消費します。効果を見る