创建表环境
TableEnvironment tableEnv = ...;
创建输入表,连接外部系统读取数据
tableEnv.executeSql("CREATE TEMPORARY TABLE inputTable ... WITH ('connector' = ... )");
注册一个表,连接到外部系统,用于输出
tableEnv.executeSql("CREATE TEMPORARY TABLE outputTable ... WITH ('connector' = ... )");
执行SQL对表进行查询转换,得到一个新的表
Table table1 = tableEnv.sqlQuery("SELECT ... FROM inputTable ...");
使用Table API对表进行查询转换,得到一个新的表
Table table2 = tableEnv.from("inputTable").select(...);
将得到的结果写入输出表
TableResult tableResult = table1.executeInsert("outputTable");
对于Flink这样的流处理框架来说,数据流和表在结构上还是有所区别的。所以使用Table API和SQL需要一个特别的运行时环境,这就是所谓的表环境(TableEnvironment)。主要负责:
这里的Catalog就是目录,与标准SQL中的概念是一致的,主要用来管理所有数据库(database)和表(table)的元数据(metadata)。通过Catalog可以方便地对数据库和表进行查询的管理,所以可以认为我们所定义的表都会挂靠在某个目录下,这样就可以快速检索。在表环境中可以由用户自定义Catalog,并在其中注册表和自定义函数(UDF)。默认
的Catalog就叫作default_catalog。
每个表和SQL的执行,都必须绑定在一个表环境(TableEnvironment)中。TableEnvironment是Table API中提供的基本接口类,可以通过调用静态的create()方法来创建一个表环境实例。方法需要传入一个环境的配置参数EnvironmentSettings,它可以指定当前表环境的执行模式和计划器(planner)。执行模式有批处理和流处理两种选择,默认是流处理模式。计划器默认使用blink planner。
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.EnvironmentSettings;
import org.apache.flink.table.api.TableEnvironment;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
public class CommonApiTest {
public static void main(String[] args) {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
StreamTableEnvironment talbeEnv = StreamTableEnvironment.create(env);
//1。定义环境配置来创建表执行环境
EnvironmentSettings settings = EnvironmentSettings.newInstance()
.inStreamingMode()
.useBlinkPlanner()
.build();
TableEnvironment tableEnv = TableEnvironment.create(settings);
//2.基于blink版本planner进行批处理
EnvironmentSettings settings2 = EnvironmentSettings.newInstance()
.inBatchMode()
.useBlinkPlanner()
.build();
TableEnvironment tableEnv3 = TableEnvironment.create(settings2);
}
}
表(Table)是关系型数据库中数据存储的基本形式,也是SQL执行的基本对象。Flink中的表是由多个行数据构成的,每个行(Row)又可以有定义好的多个列(Column)字段。整体来看,表就是固定类型的数据组成的二维矩阵。
为了方便的查询表,表环境中会维护一个目录(Catalog)和表的对应关系。所以表都是通过Catalog来进行注册创建的。表在环境中有一个唯一的ID,由三部分组成:目录(catalog)名,数据库(database)名,以及表名。在默认情况下,目录名为default_catalog,数据库名为default_database。所以如果我们直接创建一个叫做MyTable的表,它的ID就是:default_catalog.default_database.MyTable
具体创建表的方式,有通过连接器(connector)和虚拟表(virtual tables)两种。
tableEnv.executeSql("CREATE [TEMPORARY] TABLE MyTable ... WITH ('connector' = ... )");
这里的TEMPORARY关键字可以省略。这里没有定义Catalog和Database,所以都是默认的,表的完整ID就是default_catalog.default_database.MyTable。如果希望使用自定义的目录名和库名,可以在环境中进行设置:
tEnv.useCatalog("custom_catalog");
tEnv.useDatabase("custom_database");
这样创建的表完整ID就变成了custom_catalog.custom_database.MyTable。之后在表环境中创建的所有表,ID也会都以custom_catalog.custom_database作为前缀。
//2。创建表
String creatDDL = "CREATE TABLE clickTable (" +
"user STRING, " +
"url STRING, " +
"ts BIGINT " +
") WITH (" +
" 'connector' = 'filesystem',"+
" 'path' = '/Users/fei.yang4/project/learn/src/main/java/com/bigdata/plus/flink" +
"/input/clicks.txt'," +
" 'format' = 'csv'" +
")";
tableEnv.executeSql(creatDDL);
//创建一张用于输出的表
//2。创建表
String creatOutDDL = "CREATE TABLE outTable (" +
"user STRING, " +
"url STRING, " +
"ts BIGINT " +
") WITH (" +
" 'connector' = 'filesystem',"+
" 'path' = '/Users/fei.yang4/project/learn/src/main/java/com/bigdata/plus/flink" +
"/input/output.txt'," +
" 'format' = 'csv'" +
")";
tableEnv.executeSql(creatOutDDL);
Table newTable = tableEnv.sqlQuery("SELECT ... FROM MyTable ...");
这里调用了表环境的sqlQuery()方法,直接传入一条SQL语句作为参数执行查询,得到的结果是一个Table对象。Table是Table API中提供的核心接口类,就代表了一个Java中定义的表实例。
得到的newTable是一个中间转换结果,如果之后又希望直接使用这个表执行SQL,又该怎么做呢?由于newTable是一个Table对象,并没有在表环境中注册。所以我们还需要将这个中间结果表注册到环境中,才能在SQL中使用:
tableEnv.createTemporaryView("NewTable",newTable);