private StatementExecutor generateExecutor(final String sql) throws SQLException {
   StatementExecutor result =
       new StatementExecutor(shardingConnection.getShardingContext().getExecutorEngine());
   SQLRouteResult sqlRouteResult =
       shardingConnection
           .getShardingContext()
           .getSqlRouteEngine()
           .route(sql, Collections.emptyList());
   mergeContext = sqlRouteResult.getMergeContext();
   mergeContext.setExecutorEngine(shardingConnection.getShardingContext().getExecutorEngine());
   for (SQLExecutionUnit each : sqlRouteResult.getExecutionUnits()) {
     result.addStatement(
         new StatementExecutorWrapper(
             generateStatement(each.getSql(), each.getDataSource()), each));
   }
   return result;
 }
 private Statement generateStatement(final String sql, final String dataSourceName)
     throws SQLException {
   HashCode hashCode =
       Hashing.md5()
           .newHasher()
           .putString(sql, Charsets.UTF_8)
           .putString(dataSourceName, Charsets.UTF_8)
           .hash();
   if (cachedRoutedStatements.containsKey(hashCode)) {
     return cachedRoutedStatements.get(hashCode);
   }
   Connection connection = shardingConnection.getConnection(dataSourceName);
   Statement result;
   if (0 == resultSetHoldability) {
     result = connection.createStatement(resultSetType, resultSetConcurrency);
   } else {
     result =
         connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);
   }
   replayMethodsInvocation(result);
   cachedRoutedStatements.put(hashCode, result);
   return result;
 }