3. 使用sql查询csv/json文件内容,还能关联查询?
1. 简介
我们在前面的文章提到了calcite可以支持文件系统的数据源适配, 其实官方已经提供了相应的能力, 其支持csv和json的查询适配, 废话不多说, 直接展示.
2. Maven
<!-- calcite文件系统支持 -->
<dependency>
<groupId>org.apache.calcite</groupId>
<artifactId>calcite-file</artifactId>
<version>1.37.0</version>
</dependency>
<dependency>
<groupId>org.apache.calcite</groupId>
<artifactId>calcite-core</artifactId>
<version>1.37.0</version>
</dependency>
3. 数据文件准备
3.1 csv
user_info.csv
首行将来被解析成表的字段, 冒号后面是字段类型, 如果未指定类型 默认使用varchar
ID:long,姓名:string,GENDER:string,BIRTHDAY:date
100,"张三",,"2001-01-01"
110,"李四","M","2001-01-01"
120,"王五","M","2002-05-03"
130,"赵六","F","2005-09-07"
140,"张铁牛","M","2007-01-01"
3.2 json
role_info.json
[
{
"id": 123,
"name": "管理员",
"key": "manager"
},
{
"id": 234,
"name": "老师",
"key": "teacher"
},
{
"id": 345,
"name": "学生",
"key": "student"
}
]
然后将文件放到resources/file目录下
4. 核心代码
package com.ldx.calcite;
import com.google.common.collect.ImmutableMap;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.calcite.adapter.file.FileSchemaFactory;
import org.apache.calcite.jdbc.CalciteConnection;
import org.apache.calcite.schema.Schema;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.util.Sources;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.testng.collections.Maps;
import java.net.URL;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.Properties;
@Slf4j
public class CalciteFileTest {
private static Connection connection;
private static SchemaPlus rootSchema;
private static Statement statement;
@BeforeAll
@SneakyThrows
public static void beforeAll() {
Properties info = new Properties();
// 不区分sql大小写
info.setProperty("caseSensitive", "false");
// 创建Calcite连接
connection = DriverManager.getConnection("jdbc:calcite:", info);
CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
// 构建RootSchema,在Calcite中,RootSchema是所有数据源schema的parent,多个不同数据源schema可以挂在同一个RootSchema下
rootSchema = calciteConnection.getRootSchema();
final Schema schema = FileSchemaFactory.INSTANCE.create(rootSchema, "x",
ImmutableMap.of("directory", resourcePath("file"), "flavor", "scannable"));
rootSchema.add("test", schema);
// 创建SQL语句执行查询
statement = calciteConnection.createStatement();
}
@Test
@SneakyThrows
public void execute_simple_query() {
ResultSet resultSet = statement.executeQuery("SELECT * FROM test.user_info");
printResultSet(resultSet);
}
@Test
@SneakyThrows
public void test_execute_join_query() {
ResultSet resultSet = statement.executeQuery("SELECT * FROM test.user_info ui inner join test.role_info ri on ui.role_id = ri.id");
printResultSet(resultSet);
}
@AfterAll
@SneakyThrows
public static void closeResource() {
statement.close();
connection.close();
}
private static String resourcePath(String path) {
final URL url = CalciteFileTest.class.getResource("/" + path);
return Sources.of(url).file().getAbsolutePath();
}
public static void printResultSet(ResultSet resultSet) throws SQLException {
// 获取 ResultSet 元数据
ResultSetMetaData metaData = resultSet.getMetaData();
// 获取列数
int columnCount = metaData.getColumnCount();
log.info("Number of columns: {}",columnCount);
// 遍历 ResultSet 并打印结果
while (resultSet.next()) {
final Map<String, String> item = Maps.newHashMap();
// 遍历每一列并打印
for (int i = 1; i <= columnCount; i++) {
String columnName = metaData.getColumnName(i);
String columnValue = resultSet.getString(i);
item.put(columnName, columnValue);
}
log.info(item.toString());
}
}
}
其实核心代码就几行, 如下:
通过FileSchemaFactory指定文件目录和文件内容的读取方式, 默认将指定目录下的csv和json文件读取成Table, 表名就是file的名称
flavor:
SCANNABLE: 数据扫描。会更侧重于快速地读取和遍历数据。这种方式适用于需要对大量数据进行全表扫描或者范围扫描的情况,例如统计汇总操作FILTERABLE: 数据过滤。会更侧重于数据的条件筛选,比如在 SQL 查询中的WHERE子句。TRANSLATABLE: 数据转换。会更侧重于数据转换,以满足特定的查询需求或者数据处理要求。这种转换可能包括数据类型的转换(如将字符串类型的数字转换为实际的数值类型)、格式转换(如日期格式的调整)等。
// 这里的第二个参数“x”没什么意义, 源码中没用到, 可以随便填
final Schema schema = FileSchemaFactory.INSTANCE.create(rootSchema, "x",
ImmutableMap.of("directory", resourcePath("file"), "flavor", "scannable"));
// 使用目录名称为schema名称, 这里的test就是schema名称
rootSchema.add("test", schema);
calcite也可以做对应表的关联查询, 测试中csv关联json文件信息
"SELECT * FROM test.user_info ui inner join test.role_info ri on ui.role_id = ri.id"
5. 测试查询
execute_simple_query方法执行如下

test_execute_join_query方法执行如下:

3. 使用sql查询csv/json文件内容,还能关联查询?的更多相关文章
- Java 读取Json文件内容
读取json文件为String类型: import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logge ...
- skfpdb.db、cc3268.dll、system_V2.dat、JI60JS.dat文件内容、发票数据查询
cc3268.dll.skfpdb.db.xxxxx_V2.dat,system.dat,JI60JS.dat,log.dat,system_V2.dat,JI60JS_V2.dat,log_V2.d ...
- package.json文件内容介绍
概述 每个项目的根目录下面,一般都有一个package.json文件,定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称.版本.许可证等元数据).npm install命令根据这个配置文件, ...
- jquery 获取 json文件内容后,将其内容显示到 下拉列表框中,再将下拉列表中的内容,显示到文本框中
<script type="text/javascript"> $(function(){ $("#huoqv").click(function() ...
- IE10不能显示JSON文件内容
IE7,8,9下Ajax返回后,再执行跳转,会弹出阻止提示框. 所以我采用WebForm 提交思想: //导出 jv.postOpen = jv.PostOpen = jv.Export = func ...
- php 如何把中文写入json中 当json文件中还显示的是中文
/*** * 更新版本 */ function showupversionsub(){ #接受post 过来的数据 $app_type=$_POST['aap_type']; if($app_type ...
- 自定义mysql类用于快速执行数据库查询以及将查询结果转为json文件
由于每次连接数据库进行查询比较麻烦,偶尔还需要将查询结果转为json格式的文件, 因此暂时定义一个mysql的类,将这些常用的方法进行封装,便于直接调用(代码如下,个人用,没写什么注释). 注:导入了 ...
- ios本地文件内容读取,.json .plist 文件读写
ios本地文件内容读取,.json .plist 文件读写 本地文件.json .plist文件是较为常用的存储本地数据的文件,对这些文件的操作也是一种常用的基础. 本文同时提供初始化变量的比较标准的 ...
- python操作json文件获取内容
写case时,将case 写到json文件比写到,写python一定要学会处理json 以下,是要处理的json 处理操作包括:打开json文件,获取json文件内容,关闭json文件,读取内容中的对 ...
- 八、Delphi10.3读取JSON文件,并修改JSON数组一条内容后保存到文件
一.我们有一个JSON文件,如下: { "在野": [ { "城池": 0, "武将": 74, "登场年": 190 ...
随机推荐
- 关于免费笔记软件Obsidian和免费同步,长文,保存观看
前言 这段可以略过 最早使用的笔记软件(应该说是网页摘录软件)是网文快捕 CyberArticle ,但不停换电脑后当年保存的资料基本都遗失了,那可是我翻阅众多涩涩网站的精华文章. 后来网文快捕推出了 ...
- JESD79-5C_v1.30-2024 JEDEC DDR5 SOLID STATE TECHNOLOGY ASSOCIATION 最新内存技术规范
JESD79-5C_v1.30-2024 JEDEC DDR5 SOLID STATE TECHNOLOGY ASSOCIATION 最新DDR5内存技术规范 JEDEC 技术协会公布新 DDR5 ...
- .NET9 - 新功能体验(一)
被微软形容为"迄今为止最高效.最现代.最安全.最智能.性能最高的.NET版本"--.NET 9已经发布有一周了,今天想和大家一起体验一下新功能. 此次.NET 9在性能.安全性和功 ...
- Django3.0
Django3.0 简介 Django 最初被设计用于具有快速开发需求的新闻类站点,目的是要实现简单快捷的网站开发.以下内容简要介绍了如何使用 Django 实现一个数据库驱动的 Web 应用. Dj ...
- php之编译安装
1. 安装所需环境 yum -y install libxml2 libxml2-devel openssl openssl-devel curl-devel libjpeg-devel libpng ...
- 21stUESTC
数矩形 平面上有 \(n\) 个点,这 \(n\) 个点两两不重合.问这 \(n\) 个点可以组成多少个矩形 请注意:矩形的边不必平行于坐标轴. \(4 ≤ n ≤ 1000\) 保证这些点两两不重合 ...
- springboot 前后端大打包成一个JAR
1.概述 现在开发使用前后端开发机制,在部署的时候,我们需要将前后端分别打包,使用nginx 进行统一部署.这样就比较复杂,我们可以使用前后端打包到一个jar中,这样我们只需要一个包就可以了. 2.实 ...
- c++动态库详解
dmjcb个人博客 原文地址 概念 动态库, 又称动态链接库(\(Dynamic\) \(Link\) \(Library\), \(DLL\)), 是包含程序代码和数据的可执行文件, 在运行时被程序 ...
- 《前端运维》二、Nginx--2请求处理流程及核心模块
前一篇内容,我们学习了nginx的一些基本概念.安装和目录的作用.这篇文章我们来学习一些更加深入的内容. 一.Nginx请求处理流程 我们先来看张图吧: 我们看上图,首先客户端请求到Nginx服务器, ...
- IO介绍-下
中断 由外部设备引起的中断,称为外中断. 由内部错误引起的中断,称为内中断,或者是陷入.例如:非法指令,地址越界,电源故障等. 中断向量表 中断优先级 多中断源的处理方式 屏蔽中断 嵌套中断 根据 ...