如果查询包含分片键, 将分片的逻辑库转化为真实库的分片执行代码.
PartialSQLRouteExecutor#route
public RouteContext route(final ConnectionContext connectionContext, final QueryContext queryContext, final ShardingSphereRuleMetaData globalRuleMetaData, final ShardingSphereDatabase database) {
RouteContext result = new RouteContext();
Optional<String> dataSourceName = findDataSourceByHint(queryContext.getSqlStatementContext(), database.getResourceMetaData().getDataSources());
if (dataSourceName.isPresent()) {
// Hint模式直接返回
result.getRouteUnits().add(new RouteUnit(new RouteMapper(dataSourceName.get(), dataSourceName.get()), Collections.emptyList()));
return result;
}
// 如果有多个路由规则,则需要处理每个规则的不同路由策略
for (Entry<ShardingSphereRule, SQLRouter> entry : routers.entrySet()) {
if (result.getRouteUnits().isEmpty()) {
// RouteUnit --> 保存的是 逻辑库和真实库的映射关系 及 逻辑表和实际表的映射关系.
//分片路由执行的方法 ShardingSQLRouter#createRouteContext
result = entry.getValue().createRouteContext(queryContext, globalRuleMetaData, database, entry.getKey(), props, connectionContext);
} else {
entry.getValue().decorateRouteContext(result, queryContext, database, entry.getKey(), props, connectionContext);
}
}
// RouteUnit 记录的是每个数据源中的真实库/表的映射关系;
if (result.getRouteUnits().isEmpty() && 1 == database.getResourceMetaData().getDataSources()