sharding-jdbc源码解析多库表sql路由

sharding-jdbc多库多表路由

找到这个类com.dangdang.ddframe.rdb.sharding.routing.PreparedStatementRoutingEngine

找到这里

/**

* SQL路由.

* 当第一次路由时进行SQL解析,之后的路由复用第一次的解析结果.

*

* @param parameters SQL中的参数

* @return 路由结果

*/

public SQLRouteResultroute(final List parameters) {//sql路由业务方法

   if (null ==sqlStatement) {

sqlStatement =sqlRouter.parse(logicSQL, parameters.size());

   }

return sqlRouter.route(logicSQL, parameters, sqlStatement);

}

return sqlRouter.route(logicSQL, parameters, sqlStatement);

@Override

   public SQLRouteResultroute(final String logicSQL, final List parameters, final SQLStatement sqlStatement) {

final Context context = MetricsContext.start("Route SQL");

       SQLRouteResult result =new SQLRouteResult(sqlStatement);

//        如果是insert语句去生成分布式逐渐的逻辑

       if (sqlStatementinstanceof InsertStatement &&null != ((InsertStatement) sqlStatement).getGeneratedKey()) {

processGeneratedKey(parameters, (InsertStatement) sqlStatement, result);

       }

RoutingResult routingResult = route(parameters, sqlStatement);

RoutingResult routingResult = route(parameters, sqlStatement);

private RoutingResultroute(final List parameters, final SQLStatement sqlStatement) {

Collection tableNames = sqlStatement.getTables().getTableNames();

       RoutingEngine routingEngine;

//        如果表集合是1,或者是绑定表路由就走简单路由规则

       if (1 == tableNames.size() ||shardingRule.isAllBindingTables(tableNames)) {

routingEngine =new SimpleRoutingEngine(shardingRule, parameters, tableNames.iterator().next(), sqlStatement);//单表路由

       }else {

// TODO 可配置是否执行笛卡尔积

           routingEngine =new ComplexRoutingEngine(shardingRule, parameters, tableNames, sqlStatement);

       }

return routingEngine.route();//tianhe TODO 笛卡尔积

   }

进入到这个方法com.dangdang.ddframe.rdb.sharding.routing.type.complex.ComplexRoutingEngine#route

@Override

   public RoutingResultroute() {

Collection result =new ArrayList<>(logicTables.size());

       Collection bindingTableNames =new TreeSet<>(String.CASE_INSENSITIVE_ORDER);

       for (String each :logicTables) {

//            根据逻辑表查找分片规则

           Optional tableRule =shardingRule.tryFindTableRule(each);

           if (tableRule.isPresent()) {

//                如果绑定表名不包含逻辑表走简单路由

               if (!bindingTableNames.contains(each)) {

result.add(new SimpleRoutingEngine(shardingRule, parameters, tableRule.get().getLogicTable(), sqlStatement).route());

               }

//                根据逻辑表找绑定表规则配置,如果有走绑定表规则配置路由

               Optional bindingTableRule =shardingRule.findBindingTableRule(each);

               if (bindingTableRule.isPresent()) {

bindingTableNames.addAll(Lists.transform(bindingTableRule.get().getTableRules(), new Function() {

@Override

                       public Stringapply(final TableRule input) {

return input.getLogicTable();

                       }

}));

               }

}

}

log.trace("mixed tables sharding result: {}", result);

       if (result.isEmpty()) {

throw new ShardingJdbcException("Cannot find table rule and default data source with logic tables: '%s'", logicTables);

       }

if (1 == result.size()) {

return result.iterator().next();

       }

//        创建混合多库表路由结果

       return new CartesianRoutingEngine(result).route();

   }

return new CartesianRoutingEngine(result).route();

笛卡尔积路由引擎

/**

* 笛卡尔积的库表路由.

*

* @author zhangliang

*/

@RequiredArgsConstructor

@Slf4j

public final class CartesianRoutingEngineimplements RoutingEngine {

//    路由结果

   private final CollectionroutingResults;

返回到这里

@Override

   public CartesianRoutingResultroute() {

//        创建笛卡尔积路由对象

       CartesianRoutingResult result =new CartesianRoutingResult();

//        遍历数据源和逻辑表集合的映射关系

       for (Entry> entry : getDataSourceLogicTablesMap().entrySet()) {

//            获取物理表集合

           List> actualTableGroups = getActualTableGroups(entry.getKey(), entry.getValue());

//            根据数据源和物理表集合获取具体的执行单元

           List> tableUnitGroups = toTableUnitGroups(entry.getKey(), actualTableGroups);

           result.merge(entry.getKey(), getCartesianTableReferences(Sets.cartesianProduct(tableUnitGroups)));

       }

log.trace("cartesian tables sharding result: {}", result);

       return result;

   }

组装笛卡尔积结果集

Sets.cartesianProduct(tableUnitGroups)

组装笛卡尔积路由组

getCartesianTableReferences(Sets.cartesianProduct(tableUnitGroups))

组装笛卡尔积路由结果对象

result.merge

以上介绍了多库表sql路由。

返回到这里

@Override

   public SQLRouteResultroute(final String logicSQL, final List parameters, final SQLStatement sqlStatement) {

final Context context = MetricsContext.start("Route SQL");

       SQLRouteResult result =new SQLRouteResult(sqlStatement);

//        如果是insert语句去生成分布式逐渐的逻辑

       if (sqlStatementinstanceof InsertStatement &&null != ((InsertStatement) sqlStatement).getGeneratedKey()) {

processGeneratedKey(parameters, (InsertStatement) sqlStatement, result);

       }

//        进行sql路由返回路由结果

       RoutingResult routingResult = route(parameters, sqlStatement);

       SQLRewriteEngine rewriteEngine =new SQLRewriteEngine(shardingRule, logicSQL, sqlStatement);

       boolean isSingleRouting = routingResult.isSingleRouting();

       if (sqlStatementinstanceof SelectStatement &&null != ((SelectStatement) sqlStatement).getLimit()) {

processLimit(parameters, (SelectStatement) sqlStatement, isSingleRouting);

       }

SQLBuilder sqlBuilder = rewriteEngine.rewrite(!isSingleRouting);

       if (routingResultinstanceof 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)));

           }

}

MetricsContext.stop(context);

       if (showSQL) {

SQLLogger.logSQL(logicSQL, sqlStatement, result.getExecutionUnits(), parameters);

       }

return result;

   }

后面sql改写的部分下次再介绍。

说到最后

以上是混合多库多表路由源码解析,仅供参考。



关注微信公众号

sharding-jdbc源码解析多库表sql路由_第1张图片

加入技术微信群

sharding-jdbc源码解析多库表sql路由_第2张图片

你可能感兴趣的:(sharding-jdbc源码解析多库表sql路由)