美文网首页
1. 从selectList看Mybatis中一个sql 是如何

1. 从selectList看Mybatis中一个sql 是如何

作者: 元隐 | 来源:发表于2020-01-15 18:26 被阅读0次
    1. 首页https://www.jianshu.com/p/39106eac8081
    2. Configuration https://www.jianshu.com/p/97522192011b
    3. DynamicSqlSource https://www.jianshu.com/p/2938876957ab
    4. PreparedStatement https://www.jianshu.com/p/5979f2514af3
    5. Parameter https://www.jianshu.com/p/8b93b0b1b7cf
    6. InterceptorChainhttps://www.jianshu.com/p/2d28f7c1a780
    7. StatementHandler https://www.jianshu.com/p/e82e846ac680
    8. ResultSetHandler https://www.jianshu.com/p/63d61dda0f25

    致敬作者[克林顿·贝京]

    Clinton Begin is a Senior Developer and Agile Mentor for ThoughtWorks Canada. He has been building enterprise applications for nine years based on platforms such as Java and .NET. Clinton has extensive experience with agile methodologies, persistence frameworks, and relational databases. He is the original creator of the iBATIS persistence framework, which he designed in response to the challenges faced by object oriented developers dealing with enterprise relational databases

    这是一张ibatis的结构图, 略做参考

    image
    @see https://www.ibm.com/developerworks/cn/java/j-lo-ibatis-principle/index.html

    一个SQL的执行过程

    由configuration解析,获取MappedStatement, variables
    由SqlSession的executor 最终执行

    sql参数

    sql

    一个典型的SQL, 由statement,parameter,RowBounds(分页参数)组成
    如下:

    public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) 
    

    一个典型的statement

    <select id="queryById" resultType= ..>
    
    statement由注解或xml生成, 由configuration管理
    
    configuration.getMappedStatement(statement)
    MappedStatement getMappedStatement(String id)
    

    configuration详见configuration章节
    MappedStatement由XML/... StatementBuilder 产生

    paramter

    查询参数 详见paramter章节

    BoundSql

    可以看到BoundSql由sqlSource获取到. sqlSource有若干实现类, 包含我们常见的xml SqlSource, 还有annotation SqlSource
    DynamicSqlSource 详见DynamicSqlSource 章节

    public BoundSql getBoundSql(Object parameterObject) {
        BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        if (parameterMappings == null || parameterMappings.isEmpty()) {
          boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);
        }
    
        // check for nested result maps in parameter mappings (issue #30)
        for (ParameterMapping pm : boundSql.getParameterMappings()) {
          String rmId = pm.getResultMapId();
          if (rmId != null) {
            ResultMap rm = configuration.getResultMap(rmId);
            if (rm != null) {
              hasNestedResultMaps |= rm.hasNestedResultMaps();
            }
          }
        }
    
        return boundSql;
      }
    

    rowbounds

    分页参数,见 rowbounds章节

    sql执行

    Mybatis Sql执行由Executor负责
    org.apache.ibatis.executor.Executor

    每个SqlSession需要注入executor

    public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
        this.configuration = configuration;
        this.executor = executor;
        this.dirty = false;
        this.autoCommit = autoCommit;
      }
    
    Configuration如无特殊指定,采用的是SimpleExecutor
    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
        Executor executor;
        if (ExecutorType.BATCH == executorType) {
          executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
          executor = new ReuseExecutor(this, transaction);
        } else {
          executor = new SimpleExecutor(this, transaction);
        }
        if (cacheEnabled) {
          executor = new CachingExecutor(executor);
        }
        executor = (Executor) interceptorChain.pluginAll(executor);
        return executor;
      }
    
    四个executor网上对比很多, SimpleExecutor每次都会采用新用statement, 性能稍差, 但ReuseExecutor由于是session级别的, 性能提升有限. 
    

    doQuery sql执行

    interceptorChain 参见interceptorChain

     public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        Statement stmt = null;
        try {
          Configuration configuration = ms.getConfiguration();
          StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
          stmt = prepareStatement(handler, ms.getStatementLog());
          return handler.query(stmt, resultHandler);
        } finally {
          closeStatement(stmt);
        }
      }
    
    
      public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
        StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
        statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
        return statementHandler;
      }
    

    相关文章

      网友评论

          本文标题:1. 从selectList看Mybatis中一个sql 是如何

          本文链接:https://www.haomeiwen.com/subject/ujhaactx.html