sharding-jdbc源码阅读之route

sharding-jdbc是基于mybatis做的

比如我们执行一个update,mybatis会进入SimpleExecutor

image

此时的stmt如下图

image

此时的statement为ShardingPreparedStatement,终于看到sharding的影子了

然后进入

shardingPreparedStatement的execute()方法

public booleanexecute()throwsSQLException {

try{

Collection preparedStatementUnits = route();

return newPreparedStatementExecutor(

getConnection().getShardingContext().getExecutorEngine(),routeResult.getSqlStatement().getType(), preparedStatementUnits, getParameters()).execute();

}finally{

clearBatch();

}

}

然后进入route

然后进入PreparedStatementRoutingEngine的route()方法

image

先第一个parse过程,看看一个sql被parse之后,parse出来什么东东来

sqlRouter有两个实现,我们主要看下面这个

ParsingSQLRouter

image

然后进入SQLParser中的parse方法

以一个批量插入为例

下面是parse后的insertStatement

image

positionIndexMap里面的37指的是参数(values后面的参数)中的第37个

再看route过程

然后进入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)的结果如下图

image

接着执行rewrite方法,进行sql重写

SQLBuilder sqlBuilder =rewriteEngine.rewrite(!isSingleRouting);

接着看

image

看里面在循环sqlToken,但是竟然没有处理MultiInsertValuesTokens!!!!坑爹啊

看最终route出来的结果

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容