Mybatis日记

  SqlSession build:

  

  ExecutorType :SIMPLE ,REUSE, BATCH,

    SIMPLE 为默认执行器;

    REUSE 为可重用执行器,重用Statement,执行器会缓存同一个sql Statement,不重复创建。

    BTACH 为批量更新执行器。会重用重用预处理语句,该模式下insert,update,delete的返回值将无意义,也可通过设置修改。

      生命周期及作用域:

    SqlSessionFactoryBuilder: 方法作用域,该类用于创建SQLSessionFactory,一旦创建完后,就可以丢弃。

    SQLSessionFactory:应用作用域,创建后可在应用运行期间一直存在。不需要重复创建。适用于单例模式。

    SqlSession:请求或方法作用域,该类的实例是线程不安全的,因此用完之后即销毁;

  

  SQL执行流程:

    

  这里通过SQLSession中的selectList("statementId")方法查看主要的方法栈:

  

  其中包含了mybatis缓存处理、Intercepter(拦截器)的处理等操作。最终执行jdbc的Sql操作是由StatementHandler来完成。mybatis中sql mapper会转化为BoundSql,BoundSql包含了可执行sql,参数、参数类型等信息。

  StatementType : STATEMENT,PREPARED,CALLABLE

    STATEMENT: 直接执行sql,非预编译; 处理类:SimpleStatementHandler

    PREPARED:预编译处理;处理类:PreparedStatementHandler

    CALLABLE:执行存储过程;处理类:CallableStatementHandler

  StatementHandler:该接口有BaseStatementHandler和RoutingStatementHandler两个实现类。BaseStatementHandler 存在3个子类,分别对应StatementType的三种类型;BaseStatementHandler 中包含了ResultSetHandler和ParameterHandler

  StatementHandler执行sql后,会把结果交给ResultHandler来把查询结果转化为java对应的对象集合。handleResultSets()

  

 1   //处理ResultSet结果集
 2   @Override
 3   public List<Object> handleResultSets(Statement stmt) throws SQLException {
 4     ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
 5     //用于存放查询的结果对象结合,多个ResultSet集合;每个Object对应一个ResultSet,每个Object对应的是一个List<Object>对象
 6     //一般的查询只存在一个ResultSet,执行存储过程时会有多个ResultSet的情况,一般情况下multipleResults只有一个元素。
 7     final List<Object> multipleResults = new ArrayList<Object>();
 8 
 9     int resultSetCount = 0;
10     //获得第一个ResultSet对象 封装成ResultSetWrapper,主要包含了columnName、classNames、jdbcTypes
11     ResultSetWrapper rsw = getFirstResultSet(stmt);
12     //结构与multipleResults一致。
13     List<ResultMap> resultMaps = mappedStatement.getResultMaps();
14     //resultMapCount = 1
15     int resultMapCount = resultMaps.size();
16     validateResultMapsCount(rsw, resultMapCount);
17     while (rsw != null && resultMapCount > resultSetCount) {
18       //获得ResultMap对象
19       ResultMap resultMap = resultMaps.get(resultSetCount);
20       //处理ResultSet,将结果添加到multipleResults中
21       handleResultSet(rsw, resultMap, multipleResults, null);
22       //获取下一个ResultSet,并封装成ResultSetWrapper
23       rsw = getNextResultSet(stmt);
24       //清理
25       cleanUpAfterHandlingResultSet();
26       resultSetCount++;
27     }
28     //多个ResultSet结合情况下,执行存储过程时会使用
29     String[] resultSets = mappedStatement.getResultSets();
30     if (resultSets != null) {
31       while (rsw != null && resultSetCount < resultSets.length) {
32         ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
33         if (parentMapping != null) {
34           String nestedResultMapId = parentMapping.getNestedResultMapId();
35           ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
36           handleResultSet(rsw, resultMap, null, parentMapping);
37         }
38         rsw = getNextResultSet(stmt);
39         cleanUpAfterHandlingResultSet();
40         resultSetCount++;
41       }
42     }
43 
44     return collapseSingleResultList(multipleResults);
45   }
handleResultSet()
 1   //处理
 2   private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException {
 3     try {
 4       if (parentMapping != null) {
 5         //适用于存储过程,多个ResultSet的情况
 6         handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping);
 7       } else {
 8         //如果没有自定义ResultHandler,则使用DefaultResultHandler
 9         if (resultHandler == null) {
10           DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
11           handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
12           multipleResults.add(defaultResultHandler.getResultList());
13         } else {
14           //处理ResultSet的每一行结果
15           handleRowValues(rsw, resultMap, resultHandler, rowBounds, null);
16         }
17       }
18     } finally {
19       // issue #228 (close resultsets)
20       closeResultSet(rsw.getResultSet());
21     }
22   }

 

posted @ 2020-08-11 16:50  Justhing  阅读(64)  评论(0编辑  收藏  举报