公众号:帽爹的技术轮子
Sharding主要利用ANTLR4来解析SQL,以mysql为例,分析源码前可以先了解以下三点:
源码分析
1.解析入口ParsingSQLRouter#parse /**
* 解析sql
*
* @param logicSQL 逻辑sql
* @param useCache 是否缓存解析后的结果
* @return
*/
@Override
public SQLStatement parse(final String logicSQL, final boolean useCache) {
//解析前钩子,如:调用链etx
parsingHook.start(logicSQL);
try {
//解析SQL
SQLStatement result = new ShardingSQLParseEntry(databaseType, shardingMetaData.getTable(), parsingResultCache).parse(logicSQL, useCache);
//解析成功后钩子
parsingHook.finishSuccess(result, shardingMetaData.getTable());
return result;
// CHECKSTYLE:OFF
} catch (final Exception ex) {
// CHECKSTYLE:ON
//解析失败钩子
parsingHook.finishFailure(ex);
throw ex;
}
} public final class ShardingSQLParseEntry extends SQLParseEntry {
private final DatabaseType databaseType;
private final ShardingTableMetaData shardingTableMetaData;
public ShardingSQLParseEntry(final DatabaseType databaseType, final ShardingTableMetaData shardingTableMetaData, final ParsingResultCache parsingResultCache) {
super(parsingResultCache);
this.databaseType = databaseType;
this.shardingTableMetaData = shardingTableMetaData;
}
/**
* 根据sql获取解析引擎封装对象
*/
@Override
protected SQLParseEngine getSQLParseEngine(final String sql) {
//参数1:单例,加载statement、提取、过滤配置文件
//参数2:数据库类型
//参数3:需要解析sql
//参数4:分片表元数据
return new SQLParseEngine(ShardingParseRuleRegistry.getInstance(), databaseType, sql, shardingTableMetaData);
}
}
2.ShardingParseRuleRegistry.getInstance()->ParseRuleRegistry#initParseRuleDefinition加载statement、提取、过滤配置文件 private void initParseRuleDefinition() {
//利用JAXB加载META-INF/parsing-rule-definition/extractor-rule-definition.xml配置文件
ExtractorRuleDefinitionEntity generalExtractorRuleEntity = extractorRuleLoader.load(RuleDefinitionFileConstant.getExtractorRuleDefinitionFile());
//利用JAXB加载下META-INF/parsing-rule-definition/filler-rule-definition.xml配置文件
FillerRuleDefinitionEntity generalFillerRuleEntity = fillerRuleLoader.load(RuleDefinitionFileConstant.getFillerRuleDefinitionFile());
//加对应类型(sharding、masterslave、encrypt)配置文件
//META-INF/parsing-rule-definition/sharding/filler-rule-definition.xml
FillerRuleDefinitionEntity featureGeneralFillerRuleEntity = fillerRuleLoader.load(RuleDefinitionFileConstant.getFillerRuleDefinitionFile(getType()));
//根据数据库类型加载对应的配置文件
for (DatabaseType each : SQLParserFacto