在通过解析,路由,改写之后还需要做一步处理,把 生成的SQLRouteResult的对象转换成 Collection<PreparedStatementUnit>
private Collection<PreparedStatementUnit> route() throws SQLException {
Collection<PreparedStatementUnit> result = new LinkedList<>();
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 PreparedStatementUnit(each, preparedStatement));
}
}
return result;
}
从上面代码可以看到,从①出开始就是对SQLRouteResult进行数据转换
②处,通过执行的数据库操作类型,进行不同的处理
这里主要是把获得的结果组装成能够正式执行的数据库connection和 PreparedStatement,便于后面数据库的执行
//DDL
private Collection<PreparedStatement> generatePreparedStatementForDDL(final SQLExecutionUnit sqlExecutionUnit) throws SQLException {
Collection<PreparedStatement> result = new LinkedList<>();
Collection<Connection> connections = getConnection().getConnectionsForDDL(sqlExecutionUnit.getDataSource());
for (Connection each : connections) {
result.add(each.prepareStatement(sqlExecutionUnit.getSql(), resultSetType, resultSetConcurrency, resultSetHoldability));
}
return result;
}
//DML
private PreparedStatement generatePreparedStatement(final SQLExecutionUnit sqlExecutionUnit) throws SQLException {
Connection connection = getConnection().getConnection(sqlExecutionUnit.getDataSource(), routeResult.getSqlStatement().getType());
return returnGeneratedKeys ? connection.prepareStatement(sqlExecutionUnit.getSql(), Statement.RETURN_GENERATED_KEYS)
: connection.prepareStatement(sqlExecutionUnit.getSql(), resultSetType, resultSetConcurrency, resultSetHoldability);
}
然后在③处,循环遍历所有的PreparedStatement,进行处理转换成需要的数据格式 PreparedStatementUnit
其中主要是设置参数,替换参数的值,生成正式的课执行的PreparedStatement
protected void replaySetParameter(final PreparedStatement preparedStatement) {
addParameters();
for (SetParameterMethodInvocation each : setParameterMethodInvocations) {
updateParameterValues(each, parameters.get(each.getIndex() - 1));
each.invoke(preparedStatement);
}
}
private void addParameters() {
for (int i = setParameterMethodInvocations.size(); i < parameters.size(); i++) {
recordSetParameter("setObject", new Class[]{int.class, Object.class}, i + 1, parameters.get(i));
}
}
private void recordSetParameter(final String methodName, final Class[] argumentTypes, final Object... arguments) {
try {
setParameterMethodInvocations.add(new SetParameterMethodInvocation(PreparedStatement.class.getMethod(methodName, argumentTypes), arguments, arguments[1]));
} catch (final NoSuchMethodException ex) {
throw new ShardingJdbcException(ex);
}
}
到此SQL执行之前的所有准备都做完了,生成了Collection<PreparedStatementUnit>用于后续的正式执行SQL。