Mybatis中的ExecutorType


在mybatis的ExecutorType中,執行sql有三種執行模式,分別為
SIMPLE
REUSE
BATCH
這三種模式分別對應着三種執行器
SimpleExecutor、ReuseExecutor、BatchExecutor
1.SimpleExecutor

@Override
  public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
    Statement stmt = null;
    try {
      Configuration configuration = ms.getConfiguration();
      StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
      stmt = prepareStatement(handler, ms.getStatementLog());//創建statement
      return handler.update(stmt);
    } finally {
      closeStatement(stmt);//關閉statement,意味着下一次使用需要重新開啟statement
    }
  }

SimpleExecutor是每次都會關閉statement,意味着下一次使用需要重新開啟statement。
2.ReuseExecutor

@Override
 public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
   Configuration configuration = ms.getConfiguration();
   StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
   Statement stmt = prepareStatement(handler, ms.getStatementLog());
   return handler.update(stmt);//沒有關閉statement
 }

ReuseExecutor不會關閉statement,而是把statement放到緩存中。緩存的key為sql語句,value即為對應的statement。也就是說不會每一次調用都去創建一個 Statement 對象,而是會重復利用以前創建好的(如果SQL相同的話),這也就是在很多數據連接池庫中常見的 PSCache 概念 。
3.BatchExecutor

 @Override
  public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException {
    final Configuration configuration = ms.getConfiguration();
    final StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);
    final BoundSql boundSql = handler.getBoundSql();
    final String sql = boundSql.getSql();
    final Statement stmt;
    if (sql.equals(currentSql) && ms.equals(currentStatement)) {//判斷當前使用sql和statement是否是上一次的statement和sql
      int last = statementList.size() - 1;
      stmt = statementList.get(last);//如果是則取出
      applyTransactionTimeout(stmt);
     handler.parameterize(stmt);//fix Issues 322
      BatchResult batchResult = batchResultList.get(last);
      batchResult.addParameterObject(parameterObject);
    } else {
      Connection connection = getConnection(ms.getStatementLog());
      stmt = handler.prepare(connection, transaction.getTimeout());
      handler.parameterize(stmt);    //fix Issues 322
      currentSql = sql;
      currentStatement = ms;
      statementList.add(stmt);//否則創建statement並存入
      batchResultList.add(new BatchResult(ms, sql, parameterObject));
    }
  // handler.parameterize(stmt);
    handler.batch(stmt);//僅僅是存入批處理參數而不執行
    return BATCH_UPDATE_RETURN_VALUE;//始終返回一個常量
  }

總結
SimpleExecutor是一種常規執行器,每次執行都會創建一個statement,用完后關閉。
ReuseExecutor是可重用執行器,將statement存入map中,操作map中的statement而不會重復創建statement。
BatchExecutor是批處理型執行器,doUpdate預處理存儲過程或批處理操作,doQuery提交並執行過程。

性能對比

SimpleExecutor 比 ReuseExecutor 的性能要差 , 因為 SimpleExecutor 沒有做 PSCache。為什么做了 PSCache 性能就會高呢 , 因為當SQL越復雜占位符越多的時候預編譯的時間也就越長,創建一個PreparedStatement對象的時間也就越長。猜想中BatchExecutor比ReuseExecutor功能強大性能高,實際上並非如此,BatchExecutor是沒有做PSCache的。BatchExecutor 與 SimpleExecutor 和 ReuseExecutor 還有一個區別就是 , BatchExecutor 的事務是沒法自動提交的。因為 BatchExecutor 只有在調用了 SqlSession 的 commit 方法的時候,它才會去執行 executeBatch 方法。

如何在項目中設置這些模式
mybatis+spring中ExecutorType的使用

<!--配置一個可以進行批量執行的sqlSession  -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg>
    <constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>
```


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM