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 執行多次