ShardingSphere解析SQL示例詳解
引言
ShardingSphere的SQL解析,本篇文章源碼基于4.0.1版本
ShardingSphere的分片引擎從解析引擎到路由引擎到改寫引擎到執(zhí)行引擎再到歸并引擎,一步一步對分片操作進行處理,我們這篇文章先從解析引擎開始,深入分析一下Sql的解析引擎處理流程。
解析Sql的入口
SQLParseEngine這個類是sql解析引擎對應的類,通過看它的parse()方法,我們知道sql解析的過程就是構(gòu)建SQLStatement對象的過程,方法中調(diào)用了SQLParseKernel來創(chuàng)建對象,然后調(diào)用它的parse()方法來完成。因此我們把重心放在這個方法上
解析Sql
SQLParseKernel的parse()方法:
public SQLStatement parse() {
SQLAST ast = parserEngine.parse();
Collection<SQLSegment> sqlSegments = extractorEngine.extract(ast);
Map<ParserRuleContext, Integer> parameterMarkerIndexes = ast.getParameterMarkerIndexes();
return fillerEngine.fill(sqlSegments, parameterMarkerIndexes.size(), ast.getSqlStatementRule());
}
- 將原始SQL通過解析器解析為抽象語法樹
- 使用提取器根據(jù)提取規(guī)則提取Sql片段結(jié)合
- 使用填充器根據(jù)填充規(guī)則填充Sql片段生成SQL解析后的結(jié)果并返回
下面將具體看一下這三步
1. 將 SQL 解析為抽象語法樹
這一塊是對應的SQLParserEngine的parse()方法,這個方法的主要邏輯是利用工廠類SQLParserFactory來創(chuàng)建Sql解析器實例,由于不同的數(shù)據(jù)庫對應的SQL解析器也不相同,所以這一塊的邏輯也是利用了Java的SPI機制來創(chuàng)建配置的SQLParserEntry實例對象,根據(jù)不同的數(shù)據(jù)庫類型選擇不同的Sql解析器,最終會生成SQLAST對象,也就是SQL 的抽象語法樹。
2. 提取Sql片段
這一步對應的是SQLSegmentsExtractorEngine的extract()方法,返回的是所有的Sql片段的集合。
遍歷抽象語法樹中的Sql片段的提取器,提取器分為兩種類型,一種是單節(jié)點的Sql片段提取器,這時候就直接獲取Sql片段,放入集合中就可以了,另一種是樹狀節(jié)點的Sql片段提取線,這時候就需要遍歷這棵樹,將結(jié)果放入集合中。看!數(shù)據(jù)結(jié)構(gòu)之樹的遍歷用到了吧,以后別說數(shù)據(jù)結(jié)構(gòu)沒用了。。
3. 填充Sql片段,生成解析結(jié)果
第三步就是填充得到的Sql片段了,對應的是SQLStatementFillerEngine的fill()方法
public SQLStatement fill(final Collection<SQLSegment> sqlSegments, final int parameterMarkerCount, final SQLStatementRule rule) {
SQLStatement result = rule.getSqlStatementClass().newInstance();
Preconditions.checkArgument(result instanceof AbstractSQLStatement, "%s must extends AbstractSQLStatement", result.getClass().getName());
((AbstractSQLStatement) result).setParametersCount(parameterMarkerCount);
result.getAllSQLSegments().addAll(sqlSegments);
for (SQLSegment each : sqlSegments) {
Optional<SQLSegmentFiller> filler = parseRuleRegistry.findSQLSegmentFiller(databaseTypeName, each.getClass());
if (filler.isPresent()) {
filler.get().fill(each, result);
}
}
return result;
}- 獲取SQLStatement對象,對SQLStatement進行合法性進行校驗
- 設(shè)置結(jié)果的參數(shù)的個數(shù)
- 將上一步中的SQL片段集合添加到結(jié)果對象中
- 遍歷Sql片段,根據(jù)數(shù)據(jù)庫類型和Sql片段找到Sql片段過濾器,利用Sql片段過濾器來填充Sql片段
- 最后返回解析后的SQLStatement
總結(jié)
這篇文章我們講了ShardingSphere的解析Sql的功能,從它的入口開始到它具體解析Sql的過程,分三步走,第一步將原始SQL解析成抽象語法樹,第二步提取Sql片段,第三步根據(jù)數(shù)據(jù)庫類型和Sql片段選擇相應的填充器填充Sql片段,這就是解析Sql的整體過程了,希望對你理解ShardingSphere有所幫助。
更多關(guān)于ShardingSphere SQL的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Sleuth+logback 設(shè)置traceid 及自定義信息方式
這篇文章主要介紹了Sleuth+logback 設(shè)置traceid 及自定義信息方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
解決@PostConstruct注解導致的程序無法啟動(@PostConstruct的執(zhí)行)
這篇文章主要介紹了解決@PostConstruct注解導致的程序無法啟動(@PostConstruct的執(zhí)行)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01
Java二維數(shù)組與稀疏數(shù)組相互轉(zhuǎn)換實現(xiàn)詳解
在某些應用場景中需要大量的二維數(shù)組來進行數(shù)據(jù)存儲,但是二維數(shù)組中卻有著大量的無用的位置占據(jù)著內(nèi)存空間,稀疏數(shù)組就是為了優(yōu)化二維數(shù)組,節(jié)省內(nèi)存空間2022-09-09
詳解Spring Cloud Consul 實現(xiàn)服務注冊和發(fā)現(xiàn)
這篇文章主要介紹了Spring Cloud Consul 實現(xiàn)服務注冊和發(fā)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
SpringBoot接口數(shù)據(jù)加解密實戰(zhàn)記錄
現(xiàn)今對于大多數(shù)公司來說,信息安全工作尤為重要,下面這篇文章主要給大家介紹了關(guān)于SpringBoot接口數(shù)據(jù)加解密的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-07-07

