Apache Calcite精简入门与学习指导荐

1 Apache Calcite基本介绍

Apache Calcite是一个动态数据管理框架,它包含了许多典型数据库管理系统的部分,但省略了一些关键功能:数据存储、入门赘婿林阳最新章节数据处理算法和元数据存储。

基于Apache Calc刺激战场itapache配置文件详解e,我们可以为任何第三方存储引擎开发SQL查询引擎。

  • 官网地址

https://calcite.apache.org/

  • 项目地址

https://github.com/apacheitaly/calcite

2 Apache Calcite学习指导

要想了解Calcite,其实官方文档确实不妨一看。尽管官方文档会提及非常多你之前可能没有接触过的概念,但好在它文档内容不多,这样让你对SQL执行中可能涉及的一些关键术语留下一个印象,那对以后深入学习和使用Calcite还是有帮助的,毕竟如果真的想用好Calcite,或者说只是使用Calcite,这些关键术语都是需要掌握和理解的。

不过,仅仅看官方文档,那还是远远不够的。回过apache和tomcat区别头再来看Calcite的文档时,你会发现,它完全是写给“高端玩家”的,它是对Calcite高度抽象总结的文档,并不是写给初学者来进行学习的,以至于你想通过官方文档来跑个apache什么意思Quiit'sckStart,那也是相当困难入门赘婿林阳最新章节,个人觉得没有一定的折腾能学习软件力或者对SQL执行没有理解经验的话,确实不太容易达成。因此,不能刺客伍六七仅仅只看官方文档,你还需要通过其它途径获取刺杀小说家更多关于它的信学习软件息,关于初学者如何快速掌握Apache Calcite,以下是我次北固山下个人的学习软件itunes是什么意思些心刺杀小说家票房得体会:

  • 1.先简单用起来

    Calcit入门赘婿林阳最新章节e作为一个数据管理框架,首先,你得把它用学习奶茶起来才能慢慢理解它CI到底是干嘛的。理论上,通过Calcite这个组件,你可以以SQL的方式来访问任何你想要访问的数据源,比如你的文件(不管你是什么格式)、Java对象、第三方存储引擎(Re学习软件dis、KaITfka、Elasticsearch)等,所以我是用了“任何”来说明它的能力,这是它实apache认识的扩展名实在在存在的能力。

    本文档会手把手教你,怎么样通过Calcite以SQL的方式来Apache访问CSV文件、Java内部对象、Elast入门龙婿叶辰萧初然icsearch数据源。

  • 2.生产使用与思考

    所以一旦你知道Calcite可以通过SQL的方式来访问任何的数据源之后,我知道有想法的同学已经会考虑到:

    • (1)那假如在我的业务系统中,有各种各样不同的存储系统,是不是可以通过Calcite来构建一个统一的数据查询系统(一个查询入口,同时查询多种不学习英语同数据源)?

    使用者不需要感知数据存储在哪里,在他们看来,这就是一个只提供SQL查询入口的查询系统,它屏蔽了它所接入的各种存储系统的差异;

    • (2)假如业务存在一个流行的数据存储系统或者引擎,但它不支持SQL查询,我是不是可以借用Calcite来为它开发一个SQL引擎?

    答案是肯定的,Calcite是一个组件,本质上也是入门英语口语一个框架,它提供了各种扩展点来让你实现这样apache2的功能。

    当然如果你想借用Calcite针对某个存储系统开发italy一个好的SQL引擎,还是需要相当大的努力的,比如Volcan学习英语oPlanner就需要好好理解下,比较可惜的是,直到现在我也没有精力去研究它,以至于我想为Elasticsearch开发一个SQL引擎的想法都迟迟未能实现。

    所谓的“借用Calcite针对某个存储系统开发一个好的SQL次北固山下引擎”,其实在Calcite里有入门赘婿林阳免费阅读一个专业的术语,叫做“数据源适配器”。

    Calcite本身也提供了多个存储引擎的适配器,比如D刺客之王ruid、Elasticsearch、SparkSQL等等,当然开源的就并不一定得,前面之所以一直提及要重新写一个Elasticsearch的适配器,是因为我觉得Calcite本身提供的ES适配器能力apache是干嘛用的比较弱,相信用过的同学apache安装会有所体会。

  • 3.深度使用与思考

    实际上如果只是想知道Calcite怎么使用的,有哪些功能可以使用的,我们不妨站在巨人的肩膀上,看看业界的开源项目是怎么itest使用它的。

    一个不错的参考是Apache Druid,其SQL引擎正是基于Aitzypache Calcite来开发构建的,因此对于Calcite更多高级功能的使apache读音用,我们不妨去研究一下Apache Druid-SQLitem模块的源码,相信会入门街舞教学视频有非常大的收获。items

  • 4.VolcanPlanner

    有时间和精力研究一下其在Calcite的实现,个人觉得会非常不错。

本文档会手把apache是干嘛用的手教你,怎么样通过Calcite以SQL的方式来访问CSV文件、Java内部对象、Elasticsearch数据源。

对于Calcite更多的实现细节,还是自己想办法根据实际应用场景,去思考一下它的各个模块功能,比如想了解某一个功能原理,就去看其源码结构和细节,我相信这本身对个人能力的提升都是极其有帮助的。

3 通过Apache Calcite接入不同数据源

先构建一个maven项目,然后引入Calc刺客之王ite的依赖:

<dependency>
<gro刺杀小说家upId>org.入门赘婿apache.calcite</groupId>
<arapache认识的扩展名tifactId>calcite-core</artifactId>辞职报告
<version>1.20.0</version>
</dependency>此人非君子;
<dependency>
<groupId>org.apache.calcite</groupId>
<artifactId>calcite-exampl入门赘婿林阳最新章节e-csv</artifactId>
<version>1.apache配置文件详解20.0</version>
</depitunes是什么意思endency>
<dependency>
<groupId>org.apache.calcite</groupId>
<aritunesti学习软件factId>calcite-elasticsearch</artifactId>
<version>1.20.0</version>
</dependency>

3.1 接入CSV数据源

先准备一个CSV文件:

EMPNO:long,NAME:stri入门赘婿ng,DEPTNO:int,GENDER:string,CITY:string,EMPID:int,AGE:int,SLACKER:boolean,MANAGER:bool入门尽是弹冠客打一字ean,JOINEDAT:date
100,"F刺客之王red",10,,,30,25,true,false,"1996-08-03"
110,"Eric",入门街舞教学视频20,"M","San Francisco",3,80,,false,"2001-01-01"
110,"John",40,"M","Vancouver",2,,false,true,"2002-05-03"
120,"Wilma",20,"F",,1,5,,true,"2005-09it's-07"
130,"Alice",40,"Fapache安装","Vancouver",2,,falapache和tomcat区别se,true,"2007-01-01"

Calcite会把每个csv文件映射成一个SQL表。csv文件表头指定该列数据类型,根据一定规则映射到对应的SQL类型。如没有指定,则统一映射成VARCHAR。

文件刺杀小说家命名为depts.csv,Caclite会构建表名为文件名的table,即depts.

然后编写下刺杀小说家面的代码通过C辞职报告alcite以SQL方式访问数据:

// Author: xpleaf
public class CsvDemo {
pubitunes是什么意思liitemc static void main(String[] args) throws Exception {
// 0.获取csv文件的路径,注意获取到文件所在上层路径就可以了学习
String path = Objects.requireNonNull(CsvDemo.cla刺客伍六七第三季玄武国篇ss.getClassLoade入门无犬吠r().getResource("csv").getPath(apache安装));
// 1.构建CsvSchema对象,在Calcite中apache什么意思,不同数据源对应不同Schema,比如CsvSchema、DruidSchema、ElasticsearchSchema等
CsvSchema csv学习Schema = new CsvSchema(学习英语new File(path), CsvTable.Flavor.SCANNABLE);
// 2.构建Connection
// 2.1 设入门无犬吠打一字是什么字置连接参数
Properties info = new Properties();
// 不区分sql大小写
info.setProperty("caseSensiti入门龙婿叶辰萧初然ve", "apache是干嘛用的faitemlse");
// 2.2 获取标准的JDBC Connecti刺杀小说家on
Connection coitalynnection = DriverManager.getConnection("jdbc:calcite:", info);
// 2.3 获取Calcite封装的Connection
CalcitestiteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
// 3.构建RootSchema,在Calcite中,RootSchema是所有数it是什么意思呢据源schema的parent,多个不同数据源schema可以挂在同一个RootSchema下
// 以实现查询不同数据源的目的
SchemaPlus rootSchema = calciteConnection.getRootSchema();
// 4.将不同数据源Apacheschema挂载到RootSchema,这里添加CsvSchema
rootSchema.add("csv", csvScIThema);
// 5.执行SQL查询,通过SQL方式访问csv文件
String sql = "刺杀小说家票房select * from csv.deptCIs";
Statement statement = calciteConitunesnection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
// 6.遍历打印查询结刺客之王果集
Sys刺激战场tem.CIout.prin刺激战场tln(ResultSetUtil.resultString(r入门龙婿叶辰萧初然esult此生情深缘浅Set));
}
}

执行代码,其输出结果如下:

100, Fred, 10, , , 30, 25, true, faapache评分lse, 1996-08-03
110, Eric, 20, M, San Fapache配置文件详解rancisco, 3, 80, null, false, 2001-01-01
110, John, 40, M, Vancouapache配置文件详解ver, 2, null, false, true, 2002-05-03
120, Wilma, 20, F,入门尽是弹冠客打一字 , 1, 5, null, true, 2005-09-07
130,apache什么意思 Alice, 40, F, Vancouver, 2, null, fit'salse, true, 2007-01-01

思考:

csv是官方文档有CI提及的一个例子,在整体上如果需要对Calcite源码的使用有一个认识(尤其是如何开发适配器),可以基于这个demo,对照文档提及的各个概念、类,通过分析源码来进行理解,比如:

  • 1.Schema是怎么it之家构建的,在Cal入门赘婿林阳最新章节cite的位置和具体作用是什么;
  • 2.Table是怎么构建的,在Calcite的位置和具体作用是什么;
  • 3.在执行查询时是如何做SQL Parse、Validate、Optimize和执行的;

你都可以通过这个demo来一探究竟,当然,虽然我这里短短几刺激战场句话带过,实际上如果你想研究这个过入门龙婿叶辰萧初然程,可能需要花费你较多时间,我建议此人非君子不急着步子一下跨得太大,慢慢来,不急apache什么意思的。

另外入门尽是弹冠客打一字,其实通过官方文档的介绍,对于怎么去入门开发一个Caclite的数据源适配器,应该也是有一定的体会的,其实如果只是实现一个简单的适配器(不考虑太多的入门龙婿叶辰SQL优化规则),那这个难度还是不大的。

我通过这个例子,包括后面的几个例子,其实都是想告诉你,如何快速使用Calcitapache是干嘛用的e(也就是相当给你写了一个QuickitzySta入门街舞教学视频rt),从而对Calcite整体使用有一个认识,apache是干嘛用的如果你想更深度使用Calcite,建议:

  • 1.不妨看看Calcit学习英语e源码里面的入门英语口语UT,里面提供了很好的参考案例;
  • 2.但方式1可能会比较零散,你可以研读一下Apache Druid-SQL模块的源码,看一下整体上它是怎么使用的,它里面的许多高级使用技巧和方法还是十分有借鉴意义的,不妨看看入门尽是弹冠客打一字

3.2 接入Object对象数据刺客之王

3.2.1 SparkSQL接入apache认识的扩展名Object对象

有用过SparkSQL的同入门赘婿学会知道,在入门尽是弹冠客打一字Spa刺客之王rkSQL中,可以使用编程的方式来将对象实例转换为DataFrApacheame,进而注册Table,以通过SQL学习软件来访问这些对象实例:

public class _01SparkRDD2itemsDataFrame {
publi入门赘婿林阳最新章节c static void main(String[]辞职报告 args) {
Logger.getLogger("org.apache.spark").setLevel(Level.OFF);
SparkConf conf = new SparkConf()
.setMaster("local[2]")item
.setAppName(_01SparkRDD2DataFrame.class.getSimpleName())
.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
.registerKryoClasseituness(new Class[]{Person.class});
JavaSparkContext jscApache = new JavaSparkContext(conf);
SQLContext sqlContext = new SQLContext(入门jsc);
List<Person> persons = Arrays.asLi入门无犬吠st(
new Person(1, "name1", 25, 179),
new Person(2, "name2", 22, 176),
new Person(3, "name3", 27, 178),
nCIe此人非君子w Person(1, "name4", 24, 175)
);
DataFrame df = sqlContext.createDataFrame(persons, Person.class);   // 构造方法有多个,使用personsRDD的方法也是可以的
// where age > 23 and height > 176
df.select(new Column("id"),
new Column("name"),
new Citemsolumn("age"),
new Column("height")itest)
.whereitunes(new Column("age").gt(23).入门龙婿叶辰and(new Column("height").lt(学习英语179)))
.show();
df.regis入门赘婿林阳免费阅读terTempTable("person");
sqlContext.sql("select * from person where age > 23 and h入门无犬吠打一字是什么字eight < 179").shoitemw();
j学习英语sc.close();
}
}

以上代码例子来自xpleaf的文章《Spark SQL笔记整理此人非君子(二):DataFrame编程模型与操作案例》

注意这里给出的案例还是Spark 1.x的用法,Spark 2.x以及之后的版本则可能不推荐这种用法了,具体请参考Spark的官方文档。

3.2.2 Calcite接入Object对象

那么对应到Calcite,它也提itunes供了类似的方式来通过SQL访问对象实例数据。

为了进行演示,我们先构建Object对象类:

public class HrSchema {
public final Employee[] emps = {
new Employee(100, 10, "Bi入门街舞教学视频ll"CI, 10000, 1000),
new Eapache评分mployee(200, 20, "E刺客伍六七第三季玄武国篇ric", 8000, 500),apache是干嘛用的
new Employee(150,辞职报告 10, "Sebastian", 7000, null),
new Employee(it之家110, 10, "入门赘婿Theitemodore", 11500, 250),
};
@Override入门龙婿叶辰萧初然
public String toString() {
return "HrSchemaapache认识的扩展名";
}
public stat学习奶茶ic class Employee {
public int empid;
public i刺客伍六七ntitunes是什么意思 deptno;
public Strinapache是干嘛用的g name;
public float salary;
public Integer coitzymmission;
public Employee(int empid, int deptno, String name, float salary,
Integer commission) {
this.empid = empid;
this.deptno = deptno;
this.name = name;
this.sa入门无犬吠lary = salary;
this.comm学习英语ission = c刺客伍六七ommission;italy
}
@Overrideapache配置文件详解
public String toString() {
retur刺客之王n "Employee [empid: " + empid + ", deptno: " + deptno
+ ", name: " + name + "]";
}
@Override
public入门街舞教学视频 boolean equals(Objec刺杀小说家票房t obj) {
return obj == this入门赘婿
|| obj instanceof Employee
&&amit'sp; empid == ((Employee) obj).empid;
}
}
}

Calcite会将HrSchema的emps映射为一张表。

编写Calcite代码如下:

public class ObjectDemo {
publITic static void main(String[] ait是什么意思呢rgs) throws Exception {
// 1.构apache是一种什么服务器建CsvSchema对象,在Calcite中,不同数据源对应不同Schema,比如CsvScheapache安装ma、DruidSchema、ElasticsearchSchema等
Reflectiit是什么意思呢veSchema refleapache和tomcat区别ctiveSchema = new Reflectiit'sveSchema(new HrSchema());
// 2.构建Connection
// 2.1 设置连接参数
Prapache安装operties info = new Properties();
// 不区分s学习ql大小写
info.setProperty("caseSensitive", "false");
// 2.2 获取标准apache评分的JDBC Con刺客伍六七nection
Connection connection = DriverManager.getConnection("jdbc:calcitITe:", info);
// 2.3 获取Calcite封装的Co次北固山下nnectiapache2on
Calcite入门尽是弹冠客打一字Connection calciteCitemonnection = connection.unwrap(C学习软件alciteitunes是什么意思Connection.class);
// 3.构建RootSchema,在Calcite中,RootSchema是所有数据源schema的parent,多个不同数据源schema可以挂在同一个RootSchema下
// 以实现查询不同数据源的目的
SchemaPlus rootSchema = calciteConnection.getRootSchema();
// 4.将不同数据源schema挂载到RootSchema,这里添加ReflectiveScheapache和tomcat区别ma
rootSchem次北固山下a.add("hr", reflec学习奶茶tiveSchema);
// 5.执行SQL查询,通过SQL方式访问object对象实例
String sql = "select * fro学习奶茶m hr.emps";
Statement statement = calciteConnection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
// 6.遍历打印查询结果集
System.ou刺激战场t.println(入门尽是弹冠客打一字ResultSetUtil.resultString(resultSet));
}
}

执行代码,其输出结果如下:

100, 10, Bill, 10000.0, 1it's000
200, 20, Eric, 8000.0, 500
150, 10, Se入门无犬吠打一字是什么字bastian, 7000.0,刺客伍六七第三季玄武国篇 null
110, 10, Theodore, 11500.0, 250

一般在使用Calcite构建统一查询系统时,Object对象表会被用于构建刺客伍六七第三季玄武国篇数据表的元数据信息表(即表有哪些字段、字段的类型、用于构建数据表的元数据信息)等,详情可以参考Apach入门尽是弹冠客打一字e Druid-SQL源码。apache是干嘛用的

3.3 接入Elas刺客伍六七第三季玄武国篇ticsearch数据源

3.3.1 Elasticsearitzych极快速入门

不用有压力,如果你之前完全没有接触过Elasticsearch,也不用担心学习成本的问题,你就完全可以把它简单理解为一个数据库就好了,不用想那么复杂,并且,它开箱即用,没有任何部署apache是一种什么服务器成本。

下载:

httpitems://ituneswww.elastic.co/cn/downloads/elasticsearch

根据对应的操作系统下载相应的版本就可以。

下载完成后,解压,进入bin目录,执行elasticsearch.bat学习elasticsearch(取决于你的操作系统)就可apache配置文件详解以启动Elasticsearch,在浏览器上面访问localapache2host:9200,返回如下信息items

{
"name": "yeyonghaodeMacBook-Pro.loca入门l",
"cluster_name": "elasticsearch",IT
"cluster_uuid": "刺客之王6sMhfd0fSgitunes是什么意思Snqk刺杀小说家票房7M_CTmug",
"version": {
"number": "7.11.1",
"build_flavor": "defaulit是什么意思呢t",
"buil此生情深缘浅d_type": "tar",
"build_hash": "ffitunes是什么意思17057114c2199c9c1bbecc727003a907c0db7a",
"build_date": "2021-02-15T13:44:09.394items032Z",
"build_snapshot": false,
"lucene_version": "8.7.0",
"minimum_wire_compatibility_version": "6.8.0",
"minimum_index_compatiapache评分bility_ver此人非君子sion": "6.0.0-beta1"
},
"tagline": "You Know, for Search"
}

则说明服务已经部署成功items

接下来我们通过postman学习来创建index(表)和写入数据到ES:

PUT http://localhoITst:9200/teachers/_doc/1
{
"name":"xpleaf",
"aapache安装ge":26,
"rate":0.86,
"percent":0.95,
"join_time":1551058601000
}

数据写入成功后,通过postman来查询数据:

GET http://localhost:9200/teachers/_seait'srch
{
"took": 115,apache2
"timed_apache认识的扩展名out"学习: false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"tot入门赘婿林阳免费阅读al": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_indexapache2": "teachers",
"_type": "_doc",
"_id": "1",
"_score": 1.0,
"_source": {
"name": "xpleaf",
"age": 26,
"rate": 0.86,
"percent": 0.95,
"join_time": 1551058601000
}
}
]
}
}

3.3.2 Calcite接入Elasticsearch数据源

当然你可能会说,ES本身也提供了SQL的能力,但it是什么意思呢实际上它是属于x-pack组件的一部分,是商用items的,因此使用需谨慎,并且我个人觉得,它提供的SQL能力比较弱。

当然Calcite的Elasticsearch适配器其实也写得一般。

有了前面的准备之后,我们编写如下Calcite代码:

public clasapache什么意思s El入门无犬吠asticsearchDemo {
public s学习tatic void main(String[] args) throws Exception {
// 1.构建ElastiitzycsearchSchema对象,在Calcite中,不同数据源对应不同Schema,比如CsvSchema、DruidSchema、ElasticsearchSchema等
RestClient restClient = RestClient.builder(ne学习奶茶w HttpHost("localhost", 9200)).build();
ElasticsearchSchema elasticsearcapache配置文件详解hSchema = new ElasticsearchSchema(restClient, new ObjectMapper(), "teachers");
// 2.构建Connection
// 2.1 设置连接参数
Properties info = new Properties();
// 不区分sql大小写
info.setProperty("caseSensitive", "false");
//apache评分 2.2 获取标准的JDBC Connection
Connection connection = DriverManagitemser.getConnection("jdbc:calcite:", info);
// 2.3 获取Calcite封装的Connecapache是一种什么服务器tion
CalciteConnection calciteConnitunes是什么意思ection = connection.unwrap(CalciteCo学习nnection.class);
// 3.构建RootSchema,在Calcite中入门龙婿叶辰,RootSchema是所有数据源schema的parent,多个不同数学习据源schema可以挂在同一个RootSchema下
// 以实现查询不同数据源的目的
Schem学习奶茶aPlus rootS辞职报告chema = calcit入门龙婿叶辰eConnection.getRootSchema();
/入门赘婿林阳最新章节/ 4.将不同数据源schema挂载到RootSchema,这里添加Elasticsea刺杀小说家票房rchSchema
rootSchema.add("es", elasticsearchSchema);
// 5.执行SQL查询,通过SQL方式访问object对象实例
String sqlapache是一种什么服务器 = "select * from es.teachers";
Statement statement = calciteConnection.creatapache是一种什么服务器eStatement();
ResultSet res学习奶茶ultSet = statement.executeQuery入门街舞教学视频(sql);
// 6.遍历打印查询结果集
System.out.println(ResultSetUtil.resultString(resultSet));
}
}

执行代码,其输出结果如下:

{name=xpleaf, age=26, rate=0.86, percent=0.95, jitunes是什么意思oin_time=1551058601000}

4 The Next

通过前面的基本介绍和Quick学习软件Start,相信你对Apache Calcite已经有了最基本的了解,当然如果想要在生产环境真正使用Calcite,使用它来定制化构建我们的统一查询系统,仅仅了解这些肯定是入门街舞教学视频远远不够的,确实是路漫漫其修远兮刺客伍六七,不过不急,没关系的,后面有机会我将会介绍更多Calcite刺杀小说家票房的高级用法。

其实很多高级刺客伍六七第三季玄武国篇用法都是通过研读Apache Druid-SQL的此生情深缘浅源码得知的,所以我会一直强调,如果较多时间和精力,不妨阅读它的源码。

附录1:ResultSetUtil

public class ResultSetUtil {
public static String resultString(ResultSet resultSet) throws SQLException {
return resultString(resultSet, false);
}
public static Stringapache安装 resultString(ResultSet resultSet, boolean printHeader) throws SQLE入门赘婿林阳免费阅读xception {
List<List<Object>> resultList = resultList(resultSet, printHeader);
return resultStri入门尽是弹冠客打一字ng(resultList);
}
public stat刺客之王ic List<List<Object>> resultList(ResultSet ritemsesultSet) throws SQLException {
return resultList(resCIultSet, false);
}
public static String resitunesultString(List&学习英语lt;List<Object>> resultList) throws SQLException {
StringBuilder builder = new StringBuilder();
resultList.forEach(row -&刺杀小说家票房gt; {
String rowSt入门无犬吠r = row.streamitem()
.map(columnValue -学习软件> columnValue + ", ")
.collectapache读音(Collectors.joiapache是干嘛用的ning());
rowStr此人非君子 = rowStr.substring(0, rowStr.lastIndexOf(", ")) + "n";
b入门龙婿叶辰萧初然uilder.append(rowStrapache评分);
});
return builder.toString();
}
public staITtic List&入门尽是弹冠客打一字lt;Lisitemt<Object>> resultList(Rit是什么意思呢esultSet resultSet, boolean printHeadapache2er) throws SQLExc此人非君子eption {
ArrayList<List<Object>> results = new ArrayList<>();
final ResultSetMetaData metaData = resultSeitzyt.getMetaData();
finait是什么意思呢l int columnCount = metaData.getColumnCount();
if (printHeader) {
ArrayList<Object> header = new ArrayList<>();
for (int i = 1; i &itemslt;= columnCount; i++) {
he学习ader.add(metaData.getColumnName(i));
}
results.add(header);
}
while (resultSet.next()) {
ArrayList<Object> row = n此人非君子ew ArrayList<>();
fitalyor (int i = 1; i <= columnCount; i++) {
row.add(resultSet.getObject(i));
}
results.add(刺杀小说家票房row);
}
return re刺客伍六七第三季玄武国篇sults;
}
}

附录2:演示Demo源码地址

https://github.com/xpleaf/calcite-tutorial