MyBatis源碼-解讀Executor的三個實現類之BatchExecutor(批處理執行器)

在這裏插入圖片描述

Pre

MyBatis源碼-深入理解MyBatis Executor的設計思想

工程部分見
MyBatis源碼- SqlSession門面模式 & selectList 源碼解析

在這裏插入圖片描述

實際中,我們都是面向SqlSession編程的,不會直接調用Executor來執行業務邏輯,這裏我們僅僅是爲了深入瞭解下Executor體系架構才這麼搞的,切記。


Executor 執行器

在這裏插入圖片描述


接口繼承關係

在這裏插入圖片描述

這裏我們重點看下Executor的 三個實現子類。

分別是:SimpleExecutor(簡單執行器)、ReuseExecutor(重用執行器)、BatchExecutor(批處理執行器)。


BatchExecutor(重用執行器)

BatchExecutor 僅對修改操作(包括刪除)有效哈 ,對 select操作是不起作用。

BatchExecutor 主要是用於做批量更新操作的 ,底層會調用Statement的 executeBatch()方法實現批量操作

入門小demo

 @Test
    public void testBatchExecutor() throws SQLException {
        // 通過factory.openSession().getConnection()實例化JdbcTransaction ,用於構建BatchExecutor
        jdbcTransaction = new JdbcTransaction(factory.openSession().getConnection());

        // 實例化BatchExecutor
        BatchExecutor executor = new BatchExecutor(configuration, jdbcTransaction);

        // 映射SQL
        ms = configuration.getMappedStatement("com.artisan.UserMapper.updateById");

        Map map = new HashMap();
        map.put("arg0",1);
        map.put("arg1","222");

        // 調用doUpdate
        executor.doUpdate(ms,map);
        executor.doUpdate(ms,map);

        // 刷新
        executor.doFlushStatements(false);
        // 提交  否則不生效
        executor.commit(true);
     
    }

在這裏插入圖片描述


源碼

在這裏插入圖片描述

currentSql 全局變量, 非線程安全

statementList 緩存 statement
batchResultList 緩存 返回結果

 @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; 
    
   //  當前sql , 並且是當前statement
    if (sql.equals(currentSql) && ms.equals(currentStatement)) {
      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);
      batchResultList.add(new BatchResult(ms, sql, parameterObject));
    }
    handler.batch(stmt);
    return BATCH_UPDATE_RETURN_VALUE;
  }

在這裏插入圖片描述

在這裏插入圖片描述


BatchExecutor VS ReuseExecutor

看輸出 和 ReuseExecutor 感覺差不多,其實是有區別的

  • ReuseExecutor : 設置參數,執行,獲取返回結果,然後在設置參數,執行,獲取返回結果

  • BatchExecutor: 批量設置參數 , 執行 ,獲取返回結果。

BatchExecutor僅執行一次,ReuseExecutor 執行多次

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章