首页 > 数据库 >3. 使用sql查询csv/json文件内容,还能关联查询?

3. 使用sql查询csv/json文件内容,还能关联查询?

时间:2025-01-21 17:31:51浏览次数:1  
标签:info org 查询 json sql test import calcite schema

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方法执行如下:

标签:info,org,查询,json,sql,test,import,calcite,schema
From: https://www.cnblogs.com/ludangxin/p/18683656

相关文章

  • [免费]SpringBoot+Vue问卷调查管理系统【论文+源码+SQL脚本】
    大家好,我是java1234_小锋老师,看到一个不错的SpringBoot+Vue问卷调查管理系统,分享下哈。项目视频演示【免费】SpringBoot+Vue问卷调查管理系统Java毕业设计_哔哩哔哩_bilibili项目介绍传统信息的管理大部分依赖于管理人员的手工登记与管理,然而,随着近些年信息技术的迅猛发......
  • MySQL
    数据查询语句(DQL-DataQueryLanguage)执行顺序:from-->where-->groupby-->select-->having-->orderby-->limit单表查询没啥好说的,了解基本的关键字用法和函数的功能即可实现快速查询。表连接内连接innerjoin只返回满足连接条件的记录外连接outerjoin左连......
  • centos死机导致mysql无法启动解决
    3306端口没被占用2.查看日志sudocat/var/log/mysqld.log从错误日志来看,MySQL启动失败的主要原因是InnoDB存储引擎的初始化失败。具体错误信息如下:复制[ERROR]InnoDB:IgnoringtheredologduetomissingMLOG_CHECKPOINTbetweenthecheckpoint111575434andthe......
  • 修改SQL数据库中的数据
    问题希望增加、删除或修改SQL数据库中的数据。解决方案使用PD0::exec()发送一个INSERT、DELETE或UPDATE命令。使用PDO::exec()$db->exec("INSERTINTofamily(id,name)VALUES(1,'Vito')");$db->exec("DELETEFROMfamilyWHEREnameLIKE'Fredo'");$db->......
  • SQL进阶实战技巧:用户会话内行为模式挖掘
    目录0问题描述 1数据准备2问题分析3小结 往期精彩0问题描述分析用户在每个会话内的行为序列,找出最常见的前N种行为模式,并按用户分群。用户表结构和数据假设有名为user_behavior_log的用户行为日志表,包含以下字段:字段名数据类型描述user_idINT用户IDbehav......
  • Mysql并发控制和日志
    MySQL是一个广泛使用的关系数据库管理系统,在高并发环境中,如何有效地控制并发和管理日志至关重要。本文将详细介绍MySQL的并发控制机制和日志管理策略,以帮助开发人员和数据库管理员更好地理解和优化数据库性能。一、并发控制并发控制是指在多用户环境下管理对数据库的并发访问......
  • SQL查询最近的年、月、周、日的统计数据
    <selectid="statTraffic"resultType="com.nuorui.module.platform.domain.vo.StatTotalVO"><![CDATA[SELECTCASEWHEN#{dateType}=0THENYEAR(date_series.generated_date)--......
  • IDEA中将String类型转json格式
    目录问题描述问题原因解决方案结果问题描述最近做项目需要使用Ai生成json,可生成String类型的json字符串以后,IDEA识别不了,仍然将目标json视为String类型,其中的转义字符\,全都没有识别。将变量打印出来,如下:JSONString:[\n{\"options\":[{\"value\":\"基于四大维......
  • sqlite3 mysql每秒查询性能
     数据库的查询性能(如每秒查询次数,QPS,即QueriesPerSecond)取决于多种因素,包括数据库引擎、硬件配置、查询复杂度、数据量以及系统优化程度等。以下是对SQLite和MySQL每秒查询能力的比较和分析:SQLite每秒查询能力性能特点:SQLite是一个轻量级、文件系统级的数......
  • 通过sqlserver添加修改系统管理员账号.120510
    一,思路:在其他服务器B,通过sa账号远程登录需增加/修改系统管理员账号的服务器A,用sqlserver的xp_cmdshell功能,模拟cmd通过netuser命令进行添加或者修改系统管理员账号。特别提示:此解决方案只适用于服务器没有加域且忘记管理员密码的用户使用,请不要作为非法用途!二,解决方法:0,在服务......