阿飞Javaer,转载请注明原创出处,谢谢!
继续以sharding-jdbc-example-jdbc
模块中的com.dangdang.ddframe.rdb.sharding.example.jdbc.Main
为基础,剖析分库分表简单查询SQL实现–printSimpleSelect(dataSource);
,即如何执行简单的查询SQL,接下来的分析以执行SQL语句"SELECT o.* FROM t_order o where o.user_id=? AND o.order_id=?"
为例;
单表查询
Main中printSimpleSelect()
方法调用preparedStatement.executeQuery()
,即调用ShardingPreparedStatement中的executeQuery()
方法,核心源码如下:
@Override
public ResultSet executeQuery() throws SQLException {
ResultSet result;
try {
// 核心方法route(),即解析SQL如何路由执行
Collection<PreparedStatementUnit> preparedStatementUnits = route();
// 根据路由信息执行SQL
List<ResultSet> resultSets = new PreparedStatementExecutor(
getConnection().getShardingContext().getExecutorEngine(), routeResult.getSqlStatement().getType(), preparedStatementUnits, getParameters()).executeQuery();
// 对返回的结果进行merge合并
result = new ShardingResultSet(resultSets, new MergeEngine(resultSets, (SelectStatement) routeResult.getSqlStatement()).merge());
} finally {
clearBatch();
}
currentResultSet = result;
return result;
}
通过上面的源码可知,SQL查询两个核心:路由和结果合并,接下来一一分析sharding-jdbc如何实现;
单表查询之路由
接下来分析下面这段代码是如何取得路由信息的:
Collection<PreparedStatementUnit> preparedStatementUnits = route();
route()
核心源码如下:
private Collection<PreparedStatementUnit> route() throws SQLException {
Collection<PreparedStatementUnit> result = new LinkedList<>();
// 调用PreparedStatementRoutingEngine中的route()方法,route()方法调用sqlRouter.route(logicSQL, parameters, sqlStatement)
routeResult = routingEngine.route(getParameters());
for (SQLExecutionUnit each : routeResult.getExecutionUnits()) {
SQLType sqlType = routeResult.getSqlStatement().getType();
Collection<PreparedStatement> preparedStatements;
if (SQLType.DDL == sqlType) {
preparedStatements = generatePreparedStatementForDDL(each);
} else {
preparedStatements = Collections.singletonList(generatePreparedStatement(each));
}
routedStatements.addAll(preparedStatements);
for (PreparedStatement preparedStatement : preparedStatements) {
replaySetParameter(preparedStatement);
result.add(new PreparedStatem