日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql实现vpd_基于JDBC实现VPD:SQL解析篇

發(fā)布時(shí)間:2024/9/19 数据库 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql实现vpd_基于JDBC实现VPD:SQL解析篇 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

接著之前的文章《淺談基于JDBC實(shí)現(xiàn)虛擬專用數(shù)據(jù)庫(VPD)》的內(nèi)容,今天我們重點(diǎn)來說一下SQL解析的問題。

從架構(gòu)上我們可以看出來,如果要基于JDBC做VPD,不能繞開的一個(gè)問題,就是要解析SQL,那么如何解析SQL呢?其實(shí)可供選擇的方案還是很多的,比如JSqlParser、Saprk的Catalyst,亦或是直接使用Antlr,不過這里我還是更推薦使用Apache的Calcite。

首先,我們需要構(gòu)建一個(gè)解析器,這里為了方便,使用Mysql語法

SqlParser.Config config = SqlParser.configBuilder()

.setLex(Lex.MYSQL) //使用mysql 語法

.build();

String sql = "select id,name,age FROM orders";

SqlParser sqlParser = SqlParser

.create(sql, config);

然后,構(gòu)建一顆AST樹

SqlNode sqlNode = sqlParser.parseStmt();

接下來,就需要各種分支判斷,來對(duì)這個(gè)語法樹進(jìn)行遍歷,舉個(gè)簡(jiǎn)單的例子,我們將標(biāo)示,以及select項(xiàng)打印出來。

if(SqlKind.SELECT.equals(sqlNode.getKind())){

SqlSelect sqlSelect = (SqlSelect) sqlNode;

SqlNode from=sqlSelect.getFrom();

SqlNode where=sqlSelect.getWhere();

SqlNodeList selectList=sqlSelect.getSelectList();

if(SqlKind.IDENTIFIER.equals(from.getKind())){

System.out.println(from.toString());

}

selectList.getList().forEach(x->{

System.out.println("==> "+x);

});

}

所有的SQL語法都會(huì)被轉(zhuǎn)換,我們的demo使用select語句,類似的,還有SqlInsert,SqlUpdate,SqlJoin等,解析Sql是一個(gè)非常細(xì)致的工作,有興趣的同學(xué)也可以讀一下Antlr的Sql語法文件,也很有意思。

解析Sql只是整個(gè)VPD中的一環(huán),我們還需要進(jìn)行Sql的構(gòu)建。舉個(gè)簡(jiǎn)單,我們來構(gòu)建一個(gè)簡(jiǎn)單的sql查詢

SqlParserPos sqlParserPos = new SqlParserPos(1, 1);

SqlIdentifier all = new SqlIdentifier("*", null, sqlParserPos);

SqlIdentifier o = new SqlIdentifier("o", null, sqlParserPos);

SqlNodeList snl = new SqlNodeList(sqlParserPos);

snl.add(all);

SqlSelect sqls = new SqlSelect(sqlParserPos,null,snl,o,null,null,null,null,null,null,null);

System.out.println(sqls);

完整代碼如下:

package cn.flinkhub.bigdata;

import org.apache.calcite.config.Lex;

import org.apache.calcite.sql.*;

import org.apache.calcite.sql.parser.SqlParseException;

import org.apache.calcite.sql.parser.SqlParser;

import org.apache.calcite.sql.parser.SqlParserPos;

public class VPDDemo {

public static void main(String[] args) {

SqlParser.Config config = SqlParser.configBuilder()

.setLex(Lex.MYSQL) //使用mysql 語法

.build();

String sql = "select id,name,age FROM orders";

SqlParser sqlParser = SqlParser

.create(sql, config);

SqlNode sqlNode = null;

try {

System.out.println("sql = "+ sql);

sqlNode = sqlParser.parseStmt();

if(SqlKind.SELECT.equals(sqlNode.getKind())){

SqlSelect sqlSelect = (SqlSelect) sqlNode;

SqlNode from=sqlSelect.getFrom();

SqlNode where=sqlSelect.getWhere();

SqlNodeList selectList=sqlSelect.getSelectList();

if(SqlKind.IDENTIFIER.equals(from.getKind())){

System.out.println(from.toString());

}

selectList.getList().forEach(x->{

System.out.println("==> "+x);

});

}

} catch (SqlParseException e) {

throw new RuntimeException("", e);

}

SqlParserPos sqlParserPos = new SqlParserPos(1, 1);

SqlIdentifier all = new SqlIdentifier("*", null, sqlParserPos);

SqlIdentifier o = new SqlIdentifier("o", null, sqlParserPos);

SqlNodeList snl = new SqlNodeList(sqlParserPos);

snl.add(all);

SqlSelect sqls = new SqlSelect(sqlParserPos,null,snl,o,null,null,null,null,null,null,null);

System.out.println(sqls);

}

}

好了,今天就寫到這了,希望對(duì)大家能有所啟發(fā),如果你對(duì)Calcite有興趣,可以與我討論,接下來,也許會(huì)進(jìn)一步說說構(gòu)建Sql的事...

作為延伸閱讀,推薦大家讀讀王蒙大神的BLOG。非常有幫助,我以前也轉(zhuǎn)過他的文章

總結(jié)

以上是生活随笔為你收集整理的mysql实现vpd_基于JDBC实现VPD:SQL解析篇的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。