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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql ddl 语法解析工具_sharding-sphere之语法解析器

發(fā)布時間:2024/2/28 数据库 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql ddl 语法解析工具_sharding-sphere之语法解析器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

語法解析器,根據(jù)不同類型的語句有不同的語法解析器去解析成成SQLStatement,SQL解析器的類圖我用腦圖畫出來如下:

SQLParser.png

可以看到,不同的sql有不同的處理解析器去解析,解析完成之后,會將SQL解析成SQLStatement,看一下SQLParser的定義:

public interface SQLParser {

SQLStatement parse();

}

方法名

說明

SQLType getType()

獲取SQL類型,有DDL,DML,DQL,DAL,TCL

Tables getTables();

獲取表集合

Conditions getConditions();

獲取條件

List getSqlTokens();

獲取所有的SQLToken

int getParametersIndex()

獲取參數(shù)位置

void setParametersIndex(int parametersIndex)

重置參數(shù)位置

int increaseParametersIndex()

增加參數(shù)位置

除了語法解析器SQLParser,還有SQL從句解析器SQLClauseParser,SQL別名解析器AliasExpressionParser,表達式解析器BasicExpressionParser。

如下圖:

SQLClauseParser.png

SQLStatement對象是個超類,具體實現(xiàn)類有很多。按照不同的語句,返回不同的SQLStatement。

SQLStatement.png

api如下:

方法名

說明

SQLType getType()

獲取SQL類型,有DDL,DML,DQL,DAL,TCL

Tables getTables();

獲取表集合

Conditions getConditions();

獲取條件

List getSqlTokens();

獲取所有的SQLToken

int getParametersIndex()

獲取參數(shù)位置

void setParametersIndex(int parametersIndex)

重置參數(shù)位置

int increaseParametersIndex()

增加參數(shù)位置

不同的語句,ddl,dml,tcl等,有不同的語法解析器SQLParser去解析,Sharding-sphere如何根據(jù)不同的SQL去選擇不同的SQLParser?

這里和詞法分析器一樣,同樣是使用工廠模式,按照不同類型的SQL選擇不同的語法解析器。根據(jù)數(shù)據(jù)庫類型,DB類型分詞解析器獲取語法解析器。

public final class SQLParserFactory {

public static SQLParser newInstance(final DatabaseType dbType, final TokenType tokenType, final ShardingRule shardingRule, final LexerEngine lexerEngine, final ShardingMetaData shardingMetaData) {

//如果是DQL語句 select語句

if (isDQL(tokenType)) {

return getDQLParser(dbType, shardingRule, lexerEngine, shardingMetaData);

}

//DML語句 insert,update,delete語句

if (isDML(tokenType)) {

return getDMLParser(dbType, tokenType, shardingRule, lexerEngine, shardingMetaData);

}

//DDL語句 create,alter,drop,TRUNCATE語句

if (isDDL(tokenType)) {

return getDDLParser(dbType, tokenType, shardingRule, lexerEngine);

}

//TCL語句 set,commit,rollBack,savePoint,begin語句

if (isTCL(tokenType)) {

return getTCLParser(dbType, shardingRule, lexerEngine);

}

//DAL語句,use,desc,describe,show語句

if (isDAL(tokenType)) {

return getDALParser(dbType, (Keyword) tokenType, shardingRule, lexerEngine);

}

throw new SQLParsingUnsupportedException(tokenType);

}

}

這里以insert語句為例,看一下如何通過數(shù)據(jù)庫類型選擇不同的SQLParser

private static SQLParser getDMLParser(

final DatabaseType dbType, final TokenType tokenType, final ShardingRule shardingRule, final LexerEngine lexerEngine, final ShardingMetaData shardingMetaData) {

switch ((DefaultKeyword) tokenType) {

case INSERT:

//如果Insert語句

return InsertParserFactory.newInstance(dbType, shardingRule, lexerEngine, shardingMetaData);

case UPDATE:

return UpdateParserFactory.newInstance(dbType, shardingRule, lexerEngine);

case DELETE:

return DeleteParserFactory.newInstance(dbType, shardingRule, lexerEngine);

default:

throw new SQLParsingUnsupportedException(tokenType);

}

}

public final class InsertParserFactory {

public static AbstractInsertParser newInstance(final DatabaseType dbType, final ShardingRule shardingRule, final LexerEngine lexerEngine, final ShardingMetaData shardingMetaData) {

switch (dbType) {

case H2:

case MySQL:

return new MySQLInsertParser(shardingRule, lexerEngine, shardingMetaData);

case Oracle:

return new OracleInsertParser(shardingRule, lexerEngine, shardingMetaData);

case SQLServer:

return new SQLServerInsertParser(shardingRule, lexerEngine, shardingMetaData);

case PostgreSQL:

return new PostgreSQLInsertParser(shardingRule, lexerEngine, shardingMetaData);

default:

throw new UnsupportedOperationException(String.format("Cannot support database [%s].", dbType));

}

}

}

能夠看到,通過多個Factory,根據(jù)SQL語句類型(DML,DDL)等路由到不同的方法,根據(jù)具體類型(Insert,update)等找到對應的工廠模式,按照不同的數(shù)據(jù)庫類型返回具體的語法解析器SQLParser。

一條sql在執(zhí)行的時候,如何知道是什么類型的語句??

詞法分析器Lexer在解析Sql的時候,第一個分詞就是SQL的具體類型(select,update),所以在執(zhí)行sql的時候,首先調(diào)用詞法分析器解析第一個分詞,獲取語句類型,然后選擇具體的語法解析器解析。和分詞器引擎一樣,SQL語句解析器也有自己的解析引擎SQLParsingEngine

public final class SQLParsingEngine {

//數(shù)據(jù)庫類型

private final DatabaseType dbType;

//sql

private final String sql;

//分片規(guī)則

private final ShardingRule shardingRule;

private final ShardingMetaData shardingMetaData;

public SQLStatement parse(final boolean useCache) {

//是否從緩存中獲取

Optional cachedSQLStatement = getSQLStatementFromCache(useCache);

if (cachedSQLStatement.isPresent()) {

return cachedSQLStatement.get();

}

//詞法解析器,根據(jù)不同的sql,獲取不同的詞法解析引擎

LexerEngine lexerEngine = LexerEngineFactory.newInstance(dbType, sql);

//解析第一個分詞,第一個分詞能區(qū)分sql類型

lexerEngine.nextToken();

//不同的sql解析器去做解析,完成解析工作,返回SQLStatement

SQLStatement result = SQLParserFactory.newInstance(dbType, lexerEngine.getCurrentToken().getType(), shardingRule, lexerEngine, shardingMetaData).parse();

if (useCache) {

ParsingResultCache.getInstance().put(sql, result);

}

return result;

}

}

所以sql語句解析的過程如下圖:

語法解析器.png

終于把sql語法解析器的流程梳理清楚了。

下一篇,分析insert語句的流程。

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的mysql ddl 语法解析工具_sharding-sphere之语法解析器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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