php视频解析源码_自动阅读源码

php视频解析源码_自动阅读源码本章从一个select语句的执行,进入sharding-jdbc的第一步解析。 ShardingDataSource通过构造方法创建ShardingConnection。 ShardingConnection构造方法。 ShardingConnection的继承关系与Shard…

前言

本章从一个select语句的执行,进入sharding-jdbc的第一步解析

php视频解析源码_自动阅读源码

private static void select(DataSource dataSource, long userId, long orderId) throws SQLException {
    Connection connection = dataSource.getConnection();
    PreparedStatement preparedStatement = 
         connection.prepareStatement("select * from t_order where user_id = ? and order_id = ?");
    preparedStatement.setLong(1, userId);
    preparedStatement.setLong(2, orderId);
    preparedStatement.execute();
    ResultSet resultSet = preparedStatement.getResultSet();
    while (resultSet.next()) {
        System.out.print("order_id = " + resultSet.getLong(1) + ",");
        System.out.print("user_id = " + resultSet.getLong(2) + ",");
        System.out.print("address_id = " + resultSet.getLong(3) + ",");
        System.out.println("status = " + resultSet.getString(4));
    }
    resultSet.close();
    preparedStatement.close();
    connection.close();
}

一、ShardingConnection

ShardingDataSource通过构造方法创建ShardingConnection

public class ShardingDataSource extends AbstractDataSourceAdapter {
    private final ShardingRuntimeContext runtimeContext;
    public ShardingDataSource(final Map<String, DataSource> dataSourceMap, final ShardingRule shardingRule, final Properties props) throws SQLException {
        super(dataSourceMap);
        checkDataSourceType(dataSourceMap);
        runtimeContext = new ShardingRuntimeContext(dataSourceMap, shardingRule, props, getDatabaseType());
    }
    @Override
    public final ShardingConnection getConnection() {
        // TransactionTypeHolder持有ThreadLocal,用于设置事务类型,默认LOCAL
        return new ShardingConnection(getDataSourceMap(), runtimeContext, TransactionTypeHolder.get());
    }
}

ShardingConnection构造方法。

@Getter
public final class ShardingConnection extends AbstractConnectionAdapter {
    // 数据源map
    private final Map<String, DataSource> dataSourceMap;
    // sharding-jdbc运行上下文
    private final ShardingRuntimeContext runtimeContext;
    // 事务类型 默认LOCAL
    private final TransactionType transactionType;
    // 事务管理器 默认是null
    private final ShardingTransactionManager shardingTransactionManager;
    public ShardingConnection(final Map<String, DataSource> dataSourceMap, final ShardingRuntimeContext runtimeContext, final TransactionType transactionType) {
        this.dataSourceMap = dataSourceMap;
        this.runtimeContext = runtimeContext;
        this.transactionType = transactionType;
        shardingTransactionManager = runtimeContext.getShardingTransactionManagerEngine().getTransactionManager(transactionType);
    }
}

ShardingConnection的继承关系与ShardingDataSource类似。AbstractUnsupportedOperationConnection实现了不支持的Connection接口方法(抛出异常),AbstractConnectionAdapter是sharding-jdbcConnection实现类的抽象父类,提供一些方法的默认实现。

二、ShardingPreparedStatement

ShardingConnection创建ShardingPreparedStatement,把自己和sql传入ShardingPreparedStatement构造方法。

@Getter
public final class ShardingConnection extends AbstractConnectionAdapter {
	@Override
	public PreparedStatement prepareStatement(final String sql) throws SQLException {
	    return new ShardingPreparedStatement(this, sql);
	}
}

ShardingPreparedStatement构造方法。

public final class ShardingPreparedStatement extends AbstractShardingPreparedStatementAdapter {
    @Getter
    private final ShardingConnection connection;
    private final String sql;
    @Getter
    private final ParameterMetaData parameterMetaData;
    private final BasePrepareEngine prepareEngine;
    private final PreparedStatementExecutor preparedStatementExecutor;
    private final BatchPreparedStatementExecutor batchPreparedStatementExecutor;
    private final Collection<Comparable<?>> generatedValues = new LinkedList<>();
    private ExecutionContext executionContext;
    private ResultSet currentResultSet;
    public ShardingPreparedStatement(final ShardingConnection connection, final String sql) throws SQLException {
        this(connection, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT, false);
    }
    private ShardingPreparedStatement(final ShardingConnection connection, final String sql,
                                      final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability, final boolean returnGeneratedKeys) throws SQLException {
        if (Strings.isNullOrEmpty(sql)) {
            throw new SQLException(SQLExceptionConstant.SQL_STRING_NULL_OR_EMPTY);
        }
        this.connection = connection;
        this.sql = sql;
        ShardingRuntimeContext runtimeContext = connection.getRuntimeContext();
        // ParameterMetaData
        parameterMetaData = new ShardingParameterMetaData(runtimeContext.getSqlParserEngine(), sql);
        // PreparedQueryPrepareEngine
        prepareEngine = new PreparedQueryPrepareEngine(runtimeContext.getRule().toRules(), runtimeContext.getProperties(), runtimeContext.getMetaData(), runtimeContext.getSqlParserEngine());
        // PreparedStatementExecutor
        preparedStatementExecutor = new PreparedStatementExecutor(resultSetType, resultSetConcurrency, resultSetHoldability, returnGeneratedKeys, connection);
        // BatchPreparedStatementExecutor
        batchPreparedStatementExecutor = new BatchPreparedStatementExecutor(resultSetType, resultSetConcurrency, resultSetHoldability, returnGeneratedKeys, connection);
    }
}

1、ParameterMetaData

ParameterMetaData占位符参数的元数据。 构造时传入了ShardingRuntimeContext持有的SQLParserEngine

对于ShardingParameterMetaData来说只支持一个方法getParameterCountgetParameterCount获取sql中占位符个数。

@RequiredArgsConstructor
public final class ShardingParameterMetaData extends AbstractUnsupportedOperationParameterMetaData {
    private final SQLParserEngine sqlParserEngine;
    private final String sql;
    @Override
    public int getParameterCount() {
        return sqlParserEngine.parse(sql, true).getParameterCount();
    }
}

2、BasePrepareEngine

BasePrepareEngine非常重要,在它的唯一public方法中实现了解析、路由、重写三个重要步骤。

@RequiredArgsConstructor
public abstract class BasePrepareEngine {
    private final Collection<BaseRule> rules;
    private final ConfigurationProperties properties;
    private final ShardingSphereMetaData metaData;
    private final DataNodeRouter router;
    private final SQLRewriteEntry rewriter;
    
    public BasePrepareEngine(final Collection<BaseRule> rules, final ConfigurationProperties properties, final ShardingSphereMetaData metaData, final SQLParserEngine parser) {
        this.rules = rules;
        this.properties = properties;
        this.metaData = metaData;
        router = new DataNodeRouter(metaData, properties, parser);
        rewriter = new SQLRewriteEntry(metaData.getSchema(), properties);
    }
}

BasePrepareEngine构造方法,创建DataNodeRouter,负责路由;创建SQLRewriteEntry,负责创建SQLRewriteContext重写上下文。

BasePrepareEngine的实现类有两个:

  • PreparedQueryPrepareEngine:处理PrepareStatement
  • SimpleQueryPrepareEngine:处理Statement

3、PreparedStatementExecutor

PreparedStatementExecutor继承AbstractStatementExecutor抽象类负责执行sql,先看一眼构造方法,直接跳过。

public final class PreparedStatementExecutor extends AbstractStatementExecutor {
    @Getter
    private final boolean returnGeneratedKeys;
    public PreparedStatementExecutor(
            final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability, final boolean returnGeneratedKeys, final ShardingConnection shardingConnection) {
        super(resultSetType, resultSetConcurrency, resultSetHoldability, shardingConnection);
        this.returnGeneratedKeys = returnGeneratedKeys;
    }
}

三、填充占位符

ShardingPreparedStatement的抽象父类AbstractShardingPreparedStatementAdapter实现了填充占位符的功能。

public abstract class AbstractShardingPreparedStatementAdapter extends AbstractUnsupportedOperationPreparedStatement {
    private final List<SetParameterMethodInvocation> setParameterMethodInvocations = new LinkedList<>();
    @Getter
    private final List<Object> parameters = new ArrayList<>();
 	@Override
    public final void setLong(final int parameterIndex, final long x) {
        setParameter(parameterIndex, x);
    }
}

AbstractShardingPreparedStatementAdapter的setXXX方法都是将参数保存到parameters这个列表中。

private void setParameter(final int parameterIndex, final Object value) {
	if (parameters.size() == parameterIndex - 1) {
	    parameters.add(value);
	    return;
	}
	for (int i = parameters.size(); i <= parameterIndex - 1; i++) {
	    parameters.add(null);
	}
	parameters.set(parameterIndex - 1, value);
}

四、解析入口

执行SQL(preparedStatement.execute)是针对于用户而言的,实际上ShardingPrepareStatement在这个阶段做了四个重要操作:解析、路由、重写、执行php视频解析源码_自动阅读源码

public final class ShardingPreparedStatement extends AbstractShardingPreparedStatementAdapter {
  private final PreparedStatementExecutor preparedStatementExecutor;
  @Override
  public boolean execute() throws SQLException {
      try {
          // 资源清理
          preparedStatementExecutor.clear();
          // 解析 路由 重写
          prepare();
          // 初始化PreparedStatementExecutor
          initPreparedStatementExecutor();
          // 执行SQL
          return preparedStatementExecutor.execute();
      } finally {
          // 资源清理
          clearBatch();
      }
  }
}

1、资源清理

PreparedStatementExecutor的抽象父类AbstractStatementExecutor实现了clear方法,主要是清空各种集合。

@Getter
public abstract class AbstractStatementExecutor {
    // 数据库连接集合
	private final Collection<Connection> connections = new LinkedList<>();
    // 参数列表集合 最外层的List下标与statements的下标对应
    private final List<List<Object>> parameterSets = new LinkedList<>();
    // Statement集合
    private final List<Statement> statements = new LinkedList<>();
    // ResultSet集合
    private final List<ResultSet> resultSets = new CopyOnWriteArrayList<>();
    // StatementExecuteUnit集合
    private final Collection<InputGroup<StatementExecuteUnit>> inputGroups = new LinkedList<>();
	public void clear() throws SQLException {
        clearStatements(); // 关闭所有Statement
        statements.clear();
        parameterSets.clear();
        connections.clear();
        resultSets.clear();
        inputGroups.clear();
    }
    private void clearStatements() throws SQLException {
        for (Statement each : getStatements()) {
            each.close();
        }
    }
}

2、BasePrepareEngine#prepare

public final class ShardingPreparedStatement extends AbstractShardingPreparedStatementAdapter {
    private final String sql;
    private final BasePrepareEngine prepareEngine;
    private ExecutionContext executionContext;
    private void prepare() {
        // 解析 路由 重写
        executionContext = prepareEngine.prepare(sql, getParameters());
        // 从executionContext取出生成的主键ID放入generatedValues
        findGeneratedKey().ifPresent(generatedKey -> generatedValues.add(generatedKey.getGeneratedValues().getLast()));
    }
}

BasePrepareEngineprepare方法包含解析、路由、重写三个核心逻辑。

public abstract class BasePrepareEngine {
   public ExecutionContext prepare(final String sql, final List<Object> parameters) {
        // 拷贝一份参数列表
        List<Object> clonedParameters = cloneParameters(parameters);
        // 解析 & 路由
        RouteContext routeContext = executeRoute(sql, clonedParameters);
        ExecutionContext result = new ExecutionContext(routeContext.getSqlStatementContext());
        // 重写
        result.getExecutionUnits().addAll(executeRewrite(sql, clonedParameters, routeContext));
        // 打印SQL
        if (properties.<Boolean>getValue(ConfigurationPropertyKey.SQL_SHOW)) {
            SQLLogger.logSQL(sql, properties.<Boolean>getValue(ConfigurationPropertyKey.SQL_SIMPLE), result.getSqlStatementContext(), result.getExecutionUnits());
        }
        return result;
    }
}

ExecutionContext php视频解析源码_自动阅读源码 解析、路由、重写的产物就是ExecutionContext,代表sql执行的上下文。

@RequiredArgsConstructor
@Getter
public class ExecutionContext {
    private final SQLStatementContext sqlStatementContext;
    private final Collection<ExecutionUnit> executionUnits = new LinkedHashSet<>();
}

SQLStatementContext

public interface SQLStatementContext<T extends SQLStatement> {
    T getSqlStatement();
    TablesContext getTablesContext();
}

SQLStatementContext能获取SQLStatementTablesContext

例如SelectStatementContext包括查询字段(ProjectionsContext)、分组(GroupByContext)、排序(OrderByContext)、分页(PaginationContext)、表(TablesContext)等等。

@Getter
public final class SelectStatementContext extends CommonSQLStatementContext<SelectStatement> implements TableAvailable, WhereAvailable {
    private final TablesContext tablesContext;
    private final ProjectionsContext projectionsContext;
    private final GroupByContext groupByContext;
    private final OrderByContext orderByContext;
    private final PaginationContext paginationContext;
    private final boolean containsSubquery;
}

ExecutionUnit

ExecutionContext执行上下文中包含多个ExecutionUnit执行单元。

每个ExecutionUnit执行单元对应某个dataSource(如demo_ds_1)的一个SQLUnitSQL单元。

public final class ExecutionUnit {
    private final String dataSourceName;
    private final SQLUnit sqlUnit;
}

每个SQLUnitSQL单元对应一个重写完成的sql(包含?占位符)和一个parameters参数列表。

public final class SQLUnit {
    private final String sql;
    private final List<Object> parameters;
}

3、BasePrepareEngine#executeRoute

BasePrepareEngineexecuteRoute方法先将RouteDecorator注册到DataNodeRouter实例中,然后调用子类实现的route方法。

public abstract class BasePrepareEngine {
    private final Collection<BaseRule> rules中这个;
    private final DataNodeRouter router;
	private RouteContext executeRoute(final String sql, final List<Object> clonedParameters) {
        // 向DataNodeRouter实例中注册BaseRule对应的RouteDecorator
        registerRouteDecorator();
        // 解析 & 路由 子类实现
        return route(router, sql, clonedParameters);
    }
    
    private void registerRouteDecorator() {
        // 循环所有通过SPI机制注册的RouteDecorator的实现类Class
        for (Class<? extends RouteDecorator> each : OrderedRegistry.getRegisteredClasses(RouteDecorator.class)) {
            // 反射实例化这个RouteDecorator 省略
            RouteDecorator routeDecorator = createRouteDecorator(each);
            // 获取这个RouteDecorator支持的BaseRule的Class
            Class<?> ruleClass = (Class<?>) routeDecorator.getType();
            // 过滤出Collection<BaseRule> rules中这个RouteDecorator支持的BaseRule实例
            // 把这个BaseRule和routeDecorator的对应关系注册到DataNodeRouter
            rules.stream().filter(rule -> rule.getClass() == ruleClass || rule.getClass().getSuperclass() == ruleClass).collect(Collectors.toList())
                    .forEach(rule -> router.registerDecorator(rule, routeDecorator));
        }
    }
    
    protected abstract RouteContext route(DataNodeRouter dataNodeRouter, String sql, List<Object> parameters);
}

PreparedQueryPrepareEngineroute方法的实现,就是直接调用DataNodeRouterroute方法,第三个参数传true表示启用sql解析缓存。

public final class PreparedQueryPrepareEngine extends BasePrepareEngine {
    @Override
    protected RouteContext route(final DataNodeRouter dataNodeRouter, final String sql, final List<Object> parameters) {
        return dataNodeRouter.route(sql, parameters, true);
    }
}

DataNodeRouter通过SQLParserEngine解析SQLStatement,通过RouteDecorator路由。

public final class DataNodeRouter {
    // 包含数据源和表结构信息
    private final ShardingSphereMetaData metaData;
    // 配置信息
    private final ConfigurationProperties properties;
    // SQL解析引擎
    private final SQLParserEngine parserEngine;
    // BaseRule-RouteDecorator映射关系,BasePrepareEngine注入
    private final Map<BaseRule, RouteDecorator> decorators = new LinkedHashMap<>();
    // SPI钩子 暴露给用户的扩展点
    private SPIRoutingHook routingHook = new SPIRoutingHook();
    
	public RouteContext route(final String sql, final List<Object> parameters, final boolean useCache) {
        // 执行所有RoutingHook的start方法
        routingHook.start(sql);
        try {
            // 解析 & 路由
            RouteContext result = executeRoute(sql, parameters, useCache);
            // 执行所有RoutingHook的finishSuccess方法
            routingHook.finishSuccess(result, metaData.getSchema());
            return result;
        } catch (final Exception ex) {
            // 执行所有RoutingHook的finishFailure方法
            routingHook.finishFailure(ex);
            throw ex;
        }
    }
    
    private RouteContext executeRoute(final String sql, final List<Object> parameters, final boolean useCache) {
        // 解析
        RouteContext result = createRouteContext(sql, parameters, useCache);
        // 路由
        for (Entry<BaseRule, RouteDecorator> entry : decorators.entrySet()) {
            result = entry.getValue().decorate(result, metaData, entry.getKey(), properties);
        }
        return result;
    }
}

五、解析

解析是ShardingJDBC的第一步,主要是把字符串形式的sql语句,转换为对象形式的SQLStatementDataNodeRouter#createRouteContext是解析SQL的入口,直接调用了SQLParserEngineparse方法,对于PreparedQueryPrepareEngine进入该方法,useCache=true

public final class DataNodeRouter {
  // 包含数据源和表结构信息
  private final ShardingSphereMetaData metaData;
  // SQL解析引擎
  private final SQLParserEngine parserEngine;
  private RouteContext createRouteContext(final String sql, final List<Object> parameters, final boolean useCache) {
      // 将sql解析为SQLStatement
      SQLStatement sqlStatement = parserEngine.parse(sql, useCache);
      try {
          // 创建SQL上下文
          SQLStatementContext sqlStatementContext = SQLStatementContextFactory.newInstance(metaData.getSchema(), sql, parameters, sqlStatement);
          // 返回初始化的路由上下文
          return new RouteContext(sqlStatementContext, parameters, new RouteResult());
      } catch (final IndexOutOfBoundsException ex) {
          return new RouteContext(new CommonSQLStatementContext(sqlStatement), parameters, new RouteResult());
      }
  }
}  

SQLParserEngine真正执行解析SQL,这个SQLParserEngine正是之前在创建ShardingRuntimeContext时构造的SQLParserEngine

public final class SQLParserEngine {
    public SQLStatement parse(final String sql, final boolean useCache) {
        ParsingHook parsingHook = new SPIParsingHook();
        parsingHook.start(sql);
        try {
            // 执行解析
            SQLStatement result = parse0(sql, useCache);
            parsingHook.finishSuccess(result);
            return result;
        } catch (final Exception ex) {
            parsingHook.finishFailure(ex);
            throw ex;
        }
    }
}

DataNodeRouter的处理方式一样,SQLParserEngine的公共方法parse中执行了各种SPI钩子方法,最终是通过私有方法parse0实际执行SQL解析。

@RequiredArgsConstructor
public final class SQLParserEngine {
    // 数据库类型名称 例如MySQL
    private final String databaseTypeName;
    // 缓存sql - SQLStatement
    private final SQLParseResultCache cache = new SQLParseResultCache();
    
    private SQLStatement parse0(final String sql, final boolean useCache) {
        // 尝试从缓存中获取解析的SQLStatement
        if (useCache) {
            Optional<SQLStatement> cachedSQLStatement = cache.getSQLStatement(sql);
            if (cachedSQLStatement.isPresent()) {
                return cachedSQLStatement.get();
            }
        }
        // 构建ParseTree
        ParseTree parseTree = new SQLParserExecutor(databaseTypeName, sql).execute().getRootNode();
        // 构建SQLStatement
        SQLStatement result = (SQLStatement) ParseTreeVisitorFactory.newInstance(databaseTypeName, VisitorRule.valueOf(parseTree.getClass())).visit(parseTree);
        // 放入缓存
        if (useCache) {
            cache.put(sql, result);
        }
        return result;
    }
}

首先对于PrepareStatementSQLParserEngine会尝试从SQLParseResultCache缓存中获取解析结果,这个SQLParseResultCache使用的是guava的com.google.common.cache.Cache

public final class SQLParseResultCache {
    private final Cache<String, SQLStatement> cache = CacheBuilder.newBuilder().softValues()
    .initialCapacity(2000).maximumSize(65535).build();
}

接着两行代码,利用antlr(Another Tool for Language Recognition)做词法解析和语法解析,把sql转换为SQLStatement。我把两行代码中间的嵌套方法调用展开就是这样的。

// 1. 创建SQLParserExecutor
SQLParserExecutor sqlParserExecutor = new SQLParserExecutor(databaseTypeName, sql);
// 2. 根据不同的数据库类型(例如MySQLStatementParser#execute)创建解析树
ParseASTNode astNode = sqlParserExecutor.execute();
ParseTree parseTree = astNode.getRootNode();
// 3. 通过不同的数据库类型创建org.antlr.v4.runtime.tree.ParseTreeVisitor
ParseTreeVisitor parseTreeVisitor = ParseTreeVisitorFactory.newInstance(databaseTypeName, VisitorRule.valueOf(parseTree.getClass()));
// 4. 执行visit方法,最终将解析树转换为SQLStatement
SQLStatement result = (SQLStatement) parseTreeVisitor.visit(parseTree);

SelectStatement的结构是这样的。

public final class SelectStatement extends DMLStatement {
    // 字段
    private ProjectionsSegment projections;
    // 表
    private final Collection<TableReferenceSegment> tableReferences = new LinkedList<>();
    // where
    private WhereSegment where;
    // groupBy
    private GroupBySegment groupBy;
    // orderBy
    private OrderBySegment orderBy;
    // limit
    private LimitSegment limit;
    // 父statement
    private SelectStatement parentStatement;
    // lock
    private LockSegment lock;
}

回到DataNodeRouter#createRouteContext,通过SQLStatementContextFactory工厂创建SQLStatementContext

 SQLStatementContext sqlStatementContext = SQLStatementContextFactory.newInstance(metaData.getSchema(), sql, parameters, sqlStatement);

SQLStatementContextFactory先是一段if-else根据SQL类型区分。

public final class SQLStatementContextFactory {
    public static SQLStatementContext newInstance(final SchemaMetaData schemaMetaData, final String sql, final List<Object> parameters, final SQLStatement sqlStatement) {
        if (sqlStatement instanceof DMLStatement) {
            return getDMLStatementContext(schemaMetaData, sql, parameters, (DMLStatement) sqlStatement);
        }
        if (sqlStatement instanceof DDLStatement) {
            return getDDLStatementContext((DDLStatement) sqlStatement);
        }
        if (sqlStatement instanceof DCLStatement) {
            return getDCLStatementContext((DCLStatement) sqlStatement);
        }
        if (sqlStatement instanceof DALStatement) {
            return getDALStatementContext((DALStatement) sqlStatement);
        }
        return new CommonSQLStatementContext(sqlStatement);
     }
}

对于DMLStatement又是一段if-else根据SQL类型区分调用哪个构造方法。

private static SQLStatementContext getDMLStatementContext(final SchemaMetaData schemaMetaData, final String sql, final List<Object> parameters, final DMLStatement sqlStatement) {
        if (sqlStatement instanceof SelectStatement) {
            return new SelectStatementContext(schemaMetaData, sql, parameters, (SelectStatement) sqlStatement);
        }
        if (sqlStatement instanceof UpdateStatement) {
            return new UpdateStatementContext((UpdateStatement) sqlStatement);
        }
        if (sqlStatement instanceof DeleteStatement) {
            return new DeleteStatementContext((DeleteStatement) sqlStatement);
        }
        if (sqlStatement instanceof InsertStatement) {
            return new InsertStatementContext(schemaMetaData, parameters, (InsertStatement) sqlStatement);
        }
        throw new UnsupportedOperationException(String.format("Unsupported SQL statement `%s`", sqlStatement.getClass().getSimpleName()));
    }
}

SelectStatementContext的构造方法就是解析SelectStatement里的属性,构造为上下文,不细看。

@Getter
@ToString(callSuper = true)
public final class SelectStatementContext extends CommonSQLStatementContext<SelectStatement> implements TableAvailable, WhereAvailable {
    // 表
    private final TablesContext tablesContext;
    // 字段
    private final ProjectionsContext projectionsContext;
    // groupBy
    private final GroupByContext groupByContext;
    // orderBy
    private final OrderByContext orderByContext;
    // 分页
    private final PaginationContext paginationContext;
    // 是否包含子查询
    private final boolean containsSubquery;
  public SelectStatementContext(final SchemaMetaData schemaMetaData, final String sql, final List<Object> parameters, final SelectStatement sqlStatement) {
        super(sqlStatement);
        tablesContext = new TablesContext(sqlStatement.getSimpleTableSegments());
        groupByContext = new GroupByContextEngine().createGroupByContext(sqlStatement);
        orderByContext = new OrderByContextEngine().createOrderBy(sqlStatement, groupByContext);
        projectionsContext = new ProjectionsContextEngine(schemaMetaData).createProjectionsContext(sql, sqlStatement, groupByContext, orderByContext);
        paginationContext = new PaginationContextEngine().createPaginationContext(sqlStatement, projectionsContext, parameters);
        // 这里写着FIXME 写死了返回false
        containsSubquery = containsSubquery();
    }
}

总结

  • 对于dataSource.getConnection,ShardingDataSource创建的Connection实现类是ShardingConnection,它持有数据源Map和分片运行时上下文。
  • 对于connection.prepareStatement,ShardingConnection创建的PrepareStatement实现类是ShardingPrepareStatement,execute方法执行了四个关键操作,即解析、路由、重写、执行
  • SQLParserEngine的parse0方法是sql解析的核心逻辑,利用antlr(Another Tool for Language Recognition)做词法解析和语法解析,把sql转换为SQLStatement

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13064.html

(0)

相关推荐

  • mysql怎么跑代码_java预编译sql

    mysql怎么跑代码_java预编译sql工作中最常遇到的问题,怎么给线上频繁使用的大表添加字段?
    比如:给下面的用户表(user)添加年龄(age)字段。
    有同学会说,这还不简单,直接加不加完了,用下面的命令:

    2023-06-09
    146
  • Python中的Ceil函数

    Python中的Ceil函数在编写Python程序时,我们常常需要对浮点数进行向上取整的操作,例如需要获取一组数据的上限值。要实现这种操作,我们可以使用Python中的Ceil函数。本文将对Python中的Ceil函数进行详细介绍,让读者了解该函数的用法和应用场景。

    2024-08-16
    29
  • Python转义字符详解

    Python转义字符详解在Python编程中,转义字符是经常用到的一个特性。转义字符是以反斜杠符号(\)加上特殊的字母来表示的。通过转义字符,我们可以将一些特殊字符表示出来,使得字符串的表现更加丰富,也可以避免一些特殊字符出现时所带来的错误。

    2024-08-05
    36
  • Python GBK编码详解

    Python GBK编码详解GBK编码是一种双字节的文字编码方式,主要用于汉字处理。

    2024-07-13
    47
  • mysql-8.0.17绿色安装-centos7「建议收藏」

    mysql-8.0.17绿色安装-centos7「建议收藏」[root@08fc27e1d3e3 local]# yum install libaio numactl ncurses-compat-libs [root@08fc27e1d3e3 local]…

    2022-12-21
    144
  • 你瞧不起的低代码开发,阿里云总裁张建锋,他看上了「建议收藏」

    你瞧不起的低代码开发,阿里云总裁张建锋,他看上了「建议收藏」“未来不会用低代码,正如10年前不懂Excel,它将是一项基本能力。”对低代码评价之高,正是2022云栖大会,来自阿里云总裁张建锋发表的内容。普

    2022-12-14
    210
  • Python中的Finally语句

    Python中的Finally语句无论在什么编程语言中,错误处理都是一项必要的任务。在Python中,除了用try和except语句来处理代码块中的异常外,还有一个重要的语句:finally语句。finally语句表示不管try中的代码是否抛出异常,finally中的代码都会被执行。这使它比其他语句更加的强大。

    2024-05-28
    53
  • PyCharm自动导入包教程

    PyCharm自动导入包教程在进行Python编程的过程中,我们都会遇到包导入的问题。对于一些较为简单的项目,我们可以手动导入需要的包,但是在大型的项目中,手动导入包会变得十分繁琐。而PyCharm提供了自动导入包的功能,可以在代码中自动添加缺失的导入语句,提高了代码的可读性和可维护性。

    2024-04-29
    97

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注