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