BatchExecutor是实现批处理操作,会将根据相同操作通过判断sql语句和MappedStatement来将执行放到List中,来执行批处理操作。
/** * @author Jeff Butler */ public class BatchExecutor extends BaseExecutor { public static final int BATCH_UPDATE_RETURN_VALUE = Integer.MIN_VALUE + 1002; /* Statement链表**/ private final List<Statement> statementList = new ArrayList<Statement>(); /* batch结果链表**/ private final List<BatchResult> batchResultList = new ArrayList<BatchResult>(); private String currentSql; private MappedStatement currentStatement; public BatchExecutor(Configuration configuration, Transaction transaction) { super(configuration, transaction); } @Override public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException { //获得配置信息 final Configuration configuration = ms.getConfiguration(); //获得StatementHandler final StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null); final BoundSql boundSql = handler.getBoundSql(); //获得Sql语句 final String sql = boundSql.getSql(); final Statement stmt; //如果sql语句等于当前sql MappedStatement 等于当前Map碰到Statement if (sql.equals(currentSql) && ms.equals(currentStatement)) { int last = statementList.size() - 1; //获得最后一个 stmt = statementList.get(last); handler.parameterize(stmt);//fix Issues 322 //有相同的MappedStatement和参数 BatchResult batchResult = batchResultList.get(last); batchResult.addParameterObject(parameterObject); } else { //如果不存在就创建一个批处理操作 Connection connection = getConnection(ms.getStatementLog()); stmt = handler.prepare(connection); handler.parameterize(stmt); //fix Issues 322 currentSql = sql; currentStatement = ms; statementList.add(stmt); batchResultList.add(new BatchResult(ms, sql, parameterObject)); } // handler.parameterize(stmt); //最终是调用jdbc的批处理操作 handler.batch(stmt); return BATCH_UPDATE_RETURN_VALUE; } @Override public <E> List<E> doQuery(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { Statement stmt = null; try { flushStatements(); //获得配置信息 Configuration configuration = ms.getConfiguration(); //获得StatementHandler StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameterObject, rowBounds, resultHandler, boundSql); //获得连接 Connection connection = getConnection(ms.getStatementLog()); stmt = handler.prepare(connection); //获得Statement handler.parameterize(stmt); return handler.<E>query(stmt, resultHandler); } finally { closeStatement(stmt); } } /* 暂时不知道它用来处理什么**/ @Override public List<BatchResult> doFlushStatements(boolean isRollback) throws SQLException { try { List<BatchResult> results = new ArrayList<BatchResult>(); if (isRollback) { return Collections.emptyList(); } for (int i = 0, n = statementList.size(); i < n; i++) { Statement stmt = statementList.get(i); BatchResult batchResult = batchResultList.get(i); try { batchResult.setUpdateCounts(stmt.executeBatch()); MappedStatement ms = batchResult.getMappedStatement(); List<Object> parameterObjects = batchResult.getParameterObjects(); KeyGenerator keyGenerator = ms.getKeyGenerator(); if (Jdbc3KeyGenerator.class.equals(keyGenerator.getClass())) { Jdbc3KeyGenerator jdbc3KeyGenerator = (Jdbc3KeyGenerator) keyGenerator; jdbc3KeyGenerator.processBatch(ms, stmt, parameterObjects); } else if (!NoKeyGenerator.class.equals(keyGenerator.getClass())) { //issue #141 for (Object parameter : parameterObjects) { keyGenerator.processAfter(this, ms, stmt, parameter); } } } catch (BatchUpdateException e) { StringBuilder message = new StringBuilder(); message.append(batchResult.getMappedStatement().getId()) .append(" (batch index #") .append(i + 1) .append(")") .append(" failed."); if (i > 0) { message.append(" ") .append(i) .append(" prior sub executor(s) completed successfully, but will be rolled back."); } throw new BatchExecutorException(message.toString(), e, results, batchResult); } results.add(batchResult); } return results; } finally { for (Statement stmt : statementList) { closeStatement(stmt); } currentSql = null; statementList.clear(); batchResultList.clear(); } } }