首先,sharding-jdbc的原理和sharding-proxy差不多,内核不变,只是sharding-jdbc是对jdbc的一种实现,sharding-proxy是数据库的代理,因此分两块分别介绍:
1.sharding-jdbc
实现了PreparedStatement的类——ShardingPreparedStatement:
方便说明,类用橘黄色表示,方法用蓝色表示
主要覆写的几个方法:
- executeQuery
- getResultSet
- executeUpdate
- execute
- getGeneratedKeys
- addBatch
- executeBatch
- clearBatch
其中executeQuery、executeUpdate、execute方法都用到了shard()。
这个私有方法实际上调用的是BaseShardingEngine中的public SQLRouteResult shard(final String sql, final List parameters)方法。
2.sharding-proxy
sharding-proxy也调用BaseShardingEngine中的public SQLRouteResult shard(final String sql, final List parameters)这个核心方法,调用栈如下图所示:
这个方法主要是通过sql和参数,决定路由的节点并执行:
public SQLRouteResult shard(final String sql, final List<Object> parameters) {
List<Object> clonedParameters = cloneParameters(parameters);
SQLRouteResult result = executeRoute(sql, clonedParameters);
result.getRouteUnits().addAll(HintManager.isDatabaseShardingOnly() ? convert(sql, clonedParameters, result) : rewriteAndConvert(sql, clonedParameters, result));
boolean showSQL = shardingProperties.getValue(ShardingPropertiesConstant.SQL_SHOW);
if (showSQL) {
boolean showSimple = shardingProperties.getValue(ShardingPropertiesConstant.SQL_SIMPLE);
SQLLogger.logSQL(sql, showSimple, result.getSqlStatementContext(), result.getRouteUnits());
}
return result;
}
整个方法中,最重要的是executeRoute(sql, clonedParameters);
这个方法先调用了ShardingRouter的parse方法对SQL进行解析,然后调用route方法进行路由:
public SQLRouteResult route(final List<Object> parameters) {
if (null == sqlStatement) {
sqlStatement = shardingRouter.parse(logicSQL, true);
}
return masterSlaveRouter.route(shardingRouter.route(logicSQL, parameters, sqlStatement));
}
里面用到的几个关键的引擎:
- RoutingEngine:根据库表分片配置以及ShardingConditions找到目标库表,返回RoutingResult对象.
- SQLParserEngine:解析sql,返回SQLStatement作为解析的结果
- ShardingSQLRewriteEngine:根据路由结果重写sql。