sharding-jdbc是基于mybatis做的
比如我們執(zhí)行一個update,mybatis會進(jìn)入SimpleExecutor
image
此時的stmt如下圖
image
此時的statement為ShardingPreparedStatement,終于看到sharding的影子了
然后進(jìn)入
shardingPreparedStatement的execute()方法
public booleanexecute()throwsSQLException {
try{
Collection preparedStatementUnits = route();
return newPreparedStatementExecutor(
getConnection().getShardingContext().getExecutorEngine(),routeResult.getSqlStatement().getType(), preparedStatementUnits, getParameters()).execute();
}finally{
clearBatch();
}
}
然后進(jìn)入route
然后進(jìn)入PreparedStatementRoutingEngine的route()方法
image
先第一個parse過程,看看一個sql被parse之后,parse出來什么東東來
sqlRouter有兩個實(shí)現(xiàn)荧降,我們主要看下面這個
ParsingSQLRouter
image
然后進(jìn)入SQLParser中的parse方法
以一個批量插入為例
下面是parse后的insertStatement
image
positionIndexMap里面的37指的是參數(shù)(values后面的參數(shù))中的第37個
再看route過程
然后進(jìn)入ParsingSQLRouter的route方法
public SQLRouteResult route(final String logicSQL, final List<Object> parameters, final SQLStatement sqlStatement) {
SQLRouteResult result = new SQLRouteResult(sqlStatement);
if (sqlStatement instanceof InsertStatement && null != ((InsertStatement) sqlStatement).getGeneratedKey()) {
processGeneratedKey(parameters, (InsertStatement) sqlStatement, result);
}
RoutingResult routingResult = route(parameters, sqlStatement);
SQLRewriteEngine rewriteEngine = new SQLRewriteEngine(shardingRule, logicSQL, sqlStatement);
boolean isSingleRouting = routingResult.isSingleRouting();
if (sqlStatement instanceof SelectStatement && null != ((SelectStatement) sqlStatement).getLimit()) {
processLimit(parameters, (SelectStatement) sqlStatement, isSingleRouting);
}
SQLBuilder sqlBuilder = rewriteEngine.rewrite(!isSingleRouting);
if (routingResult instanceof CartesianRoutingResult) {
for (CartesianDataSource cartesianDataSource : ((CartesianRoutingResult) routingResult).getRoutingDataSources()) {
for (CartesianTableReference cartesianTableReference : cartesianDataSource.getRoutingTableReferences()) {
result.getExecutionUnits().add(new SQLExecutionUnit(cartesianDataSource.getDataSource(), rewriteEngine.generateSQL(cartesianTableReference, sqlBuilder)));
}
}
} else {
for (TableUnit each : routingResult.getTableUnits().getTableUnits()) {
result.getExecutionUnits().add(new SQLExecutionUnit(each.getDataSourceName(), rewriteEngine.generateSQL(each, sqlBuilder)));
}
}
if (showSQL) {
SQLLogger.logSQL(logicSQL, sqlStatement, result.getExecutionUnits(), parameters);
}
return result;
}
RoutingResult routingResult = route(parameters, sqlStatement)的結(jié)果如下圖
image
接著執(zhí)行rewrite方法,進(jìn)行sql重寫
SQLBuilder sqlBuilder =rewriteEngine.rewrite(!isSingleRouting);
接著看
image
看里面在循環(huán)sqlToken,但是竟然沒有處理MultiInsertValuesTokens!!!!坑爹啊
看最終route出來的結(jié)果