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 ...
随机推荐
- Gradio 和 Streamlit 安装与使用教程
最近 Sealos Devbox 有点火 ,越来越多的小伙伴都开始使用 Sealos Devbox,有位小伙伴写的文章阅读量已经接近了两万! 评论区有个小伙伴问我能不能出一篇部署 Gradio 和 S ...
- cornerstone中raft_server_req_handlers源码解析
1.概述 之前说过raft_server是cornerstone的核心,其中充满了很多req的发送,那么follower收到leader的req会怎么处理呢? 本文就是来解析cornerstone中处 ...
- Educational Codeforces Round 65 (Rated for Div
D - Bicolored RBS 给定一个括号序列,现在你必须对每一个括号涂成蓝色或红色,要求使得涂完后的红色括号和蓝色括号序列都必须是合法的括号序列,设红色括号形成的的括号序列的深度为\(dep_ ...
- docker 打包镜像过程
1.首先准备需要打成镜像的JAR包 2.编制Dockerfile文件 FROM docker.gf.com.cn/java:openjdk-8u292-arm64 MAINTAINER 8627905 ...
- Python OpenCV按照像素点图片切割
图像分割是从图像处理到图像分析的关键步骤,在目标检测.特征提取.图像识别等领域具有广泛应用.OpenCV是一个强大的计算机视觉库,提供了多种图像分割方法.本文将详细介绍如何使用Python和OpenC ...
- Qt QTtoolButton 鼠标移动到按钮上时,弹出菜单后,按钮的hover状态无法恢复的问题
需求:QTtoolButton 鼠标移到按钮上时,弹窗菜单,并且点击菜单或者其他地方,菜单关闭后,按钮的hover状态需要恢复原状. 1. 创建按钮和菜单,并安装事件过滤器 m_Menu = new ...
- VS C++ 出现debug assertion failed弹框,怎么定位代码
当VS C++ 出现debug assertion failed弹框时,想定位代码,但是按弹框出现的3个按钮都不能定位代码,这个时候,你需要打开VS界面,暂停调试,然后打开函数调用栈,找到最后执行的函 ...
- 【二分+前缀和+后缀和】codeforces 2026 D. Sums of Segments
题目 https://codeforces.com/problemset/problem/2026/D 题意 第一行输入一个正整数 \(n(1 \leq n \leq 3e5)\),第二行输入 \(n ...
- 基于知识图谱的医疗问答系统(dockerfile+docker-compose)
目录 一.搭建 Neo4j 图数据库 1.方式选择 2.Dockerfile+docker-compose部署neo4j容器 2.1.更新 yum 镜像源 2.2.安装 docker-ce 社区版 2 ...
- 【信号与系统】求使系统稳定的常数K的范围