欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Apache Calcite進行SQL解析(java代碼實例)

 更新時間:2022年01月26日 10:19:02   作者:追求無悔  
Calcite是一款開源SQL解析工具, 可以將各種SQL語句解析成抽象語法樹AST(Abstract Syntax Tree), 之后通過操作AST就可以把SQL中所要表達的算法與關(guān)系體現(xiàn)在具體代碼之中,今天通過代碼實例給大家介紹Apache Calcite進行SQL解析問題,感興趣的朋友一起看看吧

背景

當一個項目分了很多模塊,很多個服務的時候,一些公共的配置就需要統(tǒng)一管理了,于是就有了元數(shù)據(jù)驅(qū)動!

簡介

什么是Calcite?
是一款開源SQL解析工具, 可以將各種SQL語句解析成抽象語法樹AST(Abstract Syntax Tree), 之后通過操作AST就可以把SQL中所要表達的算法與關(guān)系體現(xiàn)在具體代碼之中。
Calcite能做啥?

  • SQL 解析
  • SQL 校驗
  • 查詢優(yōu)化
  • SQL 生成器
  • 數(shù)據(jù)連接

實例

今天主要是貼出一個java代碼實例,實現(xiàn)了:解析SQL語句中的表名
上代碼:
SQL語句轉(zhuǎn)化:

public static SqlNode parseStatement(String sql) {
        SqlParser parser = SqlParser.create(sql, config.getParserConfig());
        try {
            return parser.parseQuery();
        } catch (Exception e) {
            e.printStackTrace();
            throw new UnsupportedOperationException("operation not allowed");
        }
    }

解析Select中的表名:

private static Set<String> extractSourceTableInSelectSql(SqlNode sqlNode, boolean fromOrJoin) {
        if (sqlNode == null) {
            return new HashSet<>();
        }
        final SqlKind sqlKind = sqlNode.getKind();
        if (SqlKind.SELECT.equals(sqlKind)) {
            SqlSelect selectNode = (SqlSelect) sqlNode;
            Set<String> selectList = new HashSet<>(extractSourceTableInSelectSql(selectNode.getFrom(), true));
            selectNode.getSelectList().getList().stream().filter(node -> node instanceof SqlCall)
                .forEach(node -> selectList.addAll(extractSourceTableInSelectSql(node, false)));
            selectList.addAll(extractSourceTableInSelectSql(selectNode.getWhere(), false));
            selectList.addAll(extractSourceTableInSelectSql(selectNode.getHaving(), false));
            return selectList;
        if (SqlKind.JOIN.equals(sqlKind)) {
            SqlJoin sqlJoin = (SqlJoin) sqlNode;
            Set<String> joinList = new HashSet<>();
            joinList.addAll(extractSourceTableInSelectSql(sqlJoin.getLeft(), true));
            joinList.addAll(extractSourceTableInSelectSql(sqlJoin.getRight(), true));
            return joinList;

        if (SqlKind.AS.equals(sqlKind)) {
            SqlCall sqlCall = (SqlCall) sqlNode;
            return extractSourceTableInSelectSql(sqlCall.getOperandList().get(0), fromOrJoin);
        if (SqlKind.IDENTIFIER.equals(sqlKind)) {
            Set<String> identifierList = new HashSet<>();
            if (fromOrJoin) {
                SqlIdentifier sqlIdentifier = (SqlIdentifier) sqlNode;
                identifierList.add(sqlIdentifier.toString());
            }
            return identifierList;
        Set<String> defaultList = new HashSet<>();
        if (sqlNode instanceof SqlCall) {
            SqlCall call = (SqlCall) sqlNode;
            call.getOperandList()
                .forEach(node -> defaultList.addAll(extractSourceTableInSelectSql(node, false)));
        return defaultList;
    }

解析Insert語句中的表名:

private static Set<String> extractSourceTableInInsertSql(SqlNode sqlNode, boolean fromOrJoin) {
        SqlInsert sqlInsert = (SqlInsert) sqlNode;
        Set<String> insertList = new HashSet<>(extractSourceTableInSelectSql(sqlInsert.getSource(), false));
        final SqlNode targetTable = sqlInsert.getTargetTable();
        if (targetTable instanceof SqlIdentifier) {
            insertList.add(((SqlIdentifier) targetTable).toString());
        }
        return insertList;
    }

執(zhí)行效果

private static final String sql0 = "SELECT MIN(relation_id) FROM tableA JOIN TableB  GROUP BY account_instance_id, follow_account_instance_id HAVING COUNT(*)>1";

private static final String sql1 = "SELECT * FROM blog_user_relation a WHERE (a.account_instance_id,a.follow_account_instance_id) IN (SELECT account_instance_id,follow_account_instance_id FROM Blogs_info GROUP BY account_instance_id, follow_account_instance_id HAVING COUNT(*) > 1)";
private static final String sql2 = "select name from (select * from student)";
private static final String sql3 = "SELECT * FROM Student LEFT JOIN Grade ON Student.sID = Grade.gID\n" +
            "UNION\n" +
            "SELECT * FROM Student RIGHT JOIN Grade ON Student.sID = Grade.gID";
private static final String sql4 = "SELECT *\n" +
            "FROM teacher\n" +
            "WHERE birth = (SELECT MIN(birth)\n" +
            "               FROM employee)";
private static final String sql5 = "SELECT sName\n" +
            "FROM Student\n" +
            "WHERE '450' NOT IN (SELECT courseID\n" +
            "                    FROM Course\n" +
            "                    WHERE sID = Student.sID)";
final SqlNode sqlNode0 = parseStatement(sql0);
System.out.println("sqlNode0: " + extractSourceTableInSelectSql(sqlNode0, false));

結(jié)果為:

到此這篇關(guān)于Apache Calcite進行SQL解析的文章就介紹到這了,更多相關(guān)Apache Calcite解析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中如何將String轉(zhuǎn)JSONObject

    Java中如何將String轉(zhuǎn)JSONObject

    這篇文章主要介紹了Java中如何將String轉(zhuǎn)JSONObject,String類型轉(zhuǎn)JSONObject,下面有兩種方式可以進行轉(zhuǎn)換,本文結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • JavaCV攝像頭實戰(zhàn)之實現(xiàn)口罩檢測

    JavaCV攝像頭實戰(zhàn)之實現(xiàn)口罩檢測

    這篇文章主要介紹了利用JavaCV實現(xiàn)口罩檢測,功能是檢測攝像頭內(nèi)的人是否帶了口罩,把檢測結(jié)果實時標注在預覽窗口。感興趣的可以試一試
    2022-01-01
  • Java實現(xiàn)九九乘法表的完整實例(對齊版)

    Java實現(xiàn)九九乘法表的完整實例(對齊版)

    這篇文章主要給大家介紹了關(guān)于Java實現(xiàn)九九乘法表(對齊版)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Java中輸入被跳過情況的深入探究

    Java中輸入被跳過情況的深入探究

    這篇文章主要給大家介紹了關(guān)于Java中輸入被跳過情況的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • SpringMVC 中配置 Swagger 插件的教程(分享)

    SpringMVC 中配置 Swagger 插件的教程(分享)

    下面小編就為大家分享一篇SpringMVC 中配置 Swagger 插件的教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • SpringBoot整合chatGPT的項目實踐

    SpringBoot整合chatGPT的項目實踐

    本文主要介紹了SpringBoot整合chatGPT的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • Springboot與vue實例講解實現(xiàn)前后端分離的人事管理系統(tǒng)

    Springboot與vue實例講解實現(xiàn)前后端分離的人事管理系統(tǒng)

    這篇文章主要介紹了如何用Java實現(xiàn)企業(yè)人事管理系統(tǒng),文中采用springboot+vue實現(xiàn)前后端分離,感興趣的小伙伴可以學習一下
    2022-06-06
  • java分布式面試接口如何保證冪等及概念理解

    java分布式面試接口如何保證冪等及概念理解

    這篇文章主要為大家介紹了java分布式面試中接口如何保證冪等的問題解答以及概念描述,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • 淺談Springboot2.0防止XSS攻擊的幾種方式

    淺談Springboot2.0防止XSS攻擊的幾種方式

    本文主要介紹了Springboot2.0防止XSS攻擊的幾種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • Java線程之間的共享與協(xié)作詳解

    Java線程之間的共享與協(xié)作詳解

    這篇文章主要介紹了Java線程之間的共享與協(xié)作詳解,進程是操作系統(tǒng)進行資源分配的最小單位,線程是進程的一個實體,是CPU調(diào)度和分派的基本單位,它是比經(jīng)常更小的、能夠獨立運行的基本單位
    2022-07-07

最新評論