Pre
MyBatis源码-深入理解MyBatis Executor的设计思想
工程部分见 MyBatis源码- SqlSession门面模式 & selectList 源码解析
实际中,我们都是面向SqlSession编程的,不会直接调用Executor来执行业务逻辑,这里我们仅仅是为了深入了解下Executor体系架构才这么搞的,切记。
Executor 执行器
接口继承关系
这里我们重点看下Executor的 三个实现子类。
分别是:SimpleExecutor(简单执行器)、ReuseExecutor(重用执行器)、BatchExecutor(批处理执行器)。
BatchExecutor(重用执行器)
BatchExecutor 仅对修改操作(包括删除)有效哈 ,对 select操作是不起作用。
BatchExecutor 主要是用于做批量更新操作的 ,底层会调用Statement的 executeBatch()方法实现批量操作
入门小demo
代码语言:javascript复制 @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 缓存 返回结果
代码语言:javascript复制 @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 执行多次