美文网首页
sharding-jdbc源码阅读之route

sharding-jdbc源码阅读之route

作者: 7d29b558374e | 来源:发表于2017-12-05 08:25 被阅读0次

    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出来的结果

    相关文章

      网友评论

          本文标题:sharding-jdbc源码阅读之route

          本文链接:https://www.haomeiwen.com/subject/ookqixtx.html