Calcite使用SQL實(shí)現(xiàn)查詢csv/json文件內(nèi)容
1. 簡介
我們在前面的文章提到了calcite可以支持文件系統(tǒng)的數(shù)據(jù)源適配, 其實(shí)官方已經(jīng)提供了相應(yīng)的能力, 其支持csv和json的查詢適配, 廢話不多說, 直接展示.
2. Maven
<!-- calcite文件系統(tǒng)支持 --> <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. 數(shù)據(jù)文件準(zhǔn)備
3.1 csv
user_info.csv
首行將來被解析成表的字段, 冒號后面是字段類型, 如果未指定類型 默認(rèn)使用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": "學(xué)生", "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(); // 不區(qū)分sql大小寫 info.setProperty("caseSensitive", "false"); // 創(chuàng)建Calcite連接 connection = DriverManager.getConnection("jdbc:calcite:", info); CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class); // 構(gòu)建RootSchema,在Calcite中,RootSchema是所有數(shù)據(jù)源schema的parent,多個(gè)不同數(shù)據(jù)源schema可以掛在同一個(gè)RootSchema下 rootSchema = calciteConnection.getRootSchema(); final Schema schema = FileSchemaFactory.INSTANCE.create(rootSchema, "x", ImmutableMap.of("directory", resourcePath("file"), "flavor", "scannable")); rootSchema.add("test", schema); // 創(chuàng)建SQL語句執(zhí)行查詢 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 元數(shù)據(jù) ResultSetMetaData metaData = resultSet.getMetaData(); // 獲取列數(shù) int columnCount = metaData.getColumnCount(); log.info("Number of columns: {}",columnCount); // 遍歷 ResultSet 并打印結(jié)果 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()); } } }
其實(shí)核心代碼就幾行, 如下:
通過FileSchemaFactory
指定文件目錄和文件內(nèi)容的讀取方式, 默認(rèn)將指定目錄下的csv和json文件讀取成Table
, 表名就是file的名稱
flavor
:
SCANNABLE
: 數(shù)據(jù)掃描。會(huì)更側(cè)重于快速地讀取和遍歷數(shù)據(jù)。這種方式適用于需要對大量數(shù)據(jù)進(jìn)行全表掃描或者范圍掃描的情況,例如統(tǒng)計(jì)匯總操作FILTERABLE
: 數(shù)據(jù)過濾。會(huì)更側(cè)重于數(shù)據(jù)的條件篩選,比如在 SQL 查詢中的WHERE子句。TRANSLATABLE
: 數(shù)據(jù)轉(zhuǎn)換。會(huì)更側(cè)重于數(shù)據(jù)轉(zhuǎn)換,以滿足特定的查詢需求或者數(shù)據(jù)處理要求。這種轉(zhuǎn)換可能包括數(shù)據(jù)類型的轉(zhuǎn)換(如將字符串類型的數(shù)字轉(zhuǎn)換為實(shí)際的數(shù)值類型)、格式轉(zhuǎn)換(如日期格式的調(diào)整)等。
// 這里的第二個(gè)參數(shù)“x”沒什么意義, 源碼中沒用到, 可以隨便填 final Schema schema = FileSchemaFactory.INSTANCE.create(rootSchema, "x", ImmutableMap.of("directory", resourcePath("file"), "flavor", "scannable")); // 使用目錄名稱為schema名稱, 這里的test就是schema名稱 rootSchema.add("test", schema);
calcite也可以做對應(yīng)表的關(guān)聯(lián)查詢, 測試中csv關(guān)聯(lián)json文件信息
"SELECT * FROM test.user_info ui inner join test.role_info ri on ui.role_id = ri.id"
5. 測試查詢
execute_simple_query方法執(zhí)行如下
test_execute_join_query方法執(zhí)行如下:
以上就是Calcite使用SQL實(shí)現(xiàn)查詢csv/json文件內(nèi)容的詳細(xì)內(nèi)容,更多關(guān)于Calcite SQL查詢csv/json的資料請關(guān)注腳本之家其它相關(guān)文章!
- SQL Server中將查詢結(jié)果轉(zhuǎn)換為Json格式腳本分享
- mysql導(dǎo)出查詢結(jié)果到csv的實(shí)現(xiàn)方法
- mysql實(shí)現(xiàn)查詢結(jié)果導(dǎo)出csv文件及導(dǎo)入csv文件到數(shù)據(jù)庫操作
- Apache Calcite 實(shí)現(xiàn)方言轉(zhuǎn)換的代碼
- SQLServer中JSON文檔型數(shù)據(jù)的查詢問題解決
- Apache Calcite進(jìn)行SQL解析(java代碼實(shí)例)
- Calcite使用SQL實(shí)現(xiàn)查詢excel內(nèi)容
相關(guān)文章
Java中String.format的使用方法總結(jié)
這篇文章主要介紹了Java中String.format的用法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-03-03Java中的javaBean、vo、entity、domain和pojo
這篇文章主要介紹了Java中的javaBean、vo、entity、domain和pojo用法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Java簡單實(shí)現(xiàn)銀行ATM系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java簡單實(shí)現(xiàn)銀行ATM系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05關(guān)于@Scheduled注解的任務(wù)為什么不執(zhí)行的問題
這篇文章主要介紹了關(guān)于@Scheduled注解的任務(wù)為什么不執(zhí)行的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09關(guān)于Java 中的 Lambda 表達(dá)式
這篇文章主要介紹了關(guān)于Java 中的 Lambda 表達(dá)式,Lambda 表達(dá)式是 Java 涉足函數(shù)式編程的過程。它接受參數(shù)并將其應(yīng)用于表達(dá)式或代碼塊,下面一起進(jìn)入文章查看詳細(xì)內(nèi)容2021-11-11SpringBoot中注冊Bean的10種方式總結(jié)
在Spring Boot應(yīng)用中,Bean是構(gòu)成應(yīng)用的核心組件,Spring容器負(fù)責(zé)管理這些Bean,包括它們的創(chuàng)建、配置、組裝、管理和銷毀,在Spring Boot中,有多種方式可以注冊Bean,本文將詳細(xì)介紹這些不同的注冊方式,并給出相應(yīng)的示例代碼和適用場景,需要的朋友可以參考下2024-08-08