From 59c2e528f80bebbb972cd9b08289daa6d377bc3c Mon Sep 17 00:00:00 2001 From: mao-pc <2261744549@qq.com> Date: Tue, 26 May 2020 15:10:47 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AF=B9BatchExecutor=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=B8=AD=E6=96=87=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/ibatis/executor/BatchExecutor.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/apache/ibatis/executor/BatchExecutor.java b/src/main/java/org/apache/ibatis/executor/BatchExecutor.java index c290cdafc5..f64702e1ae 100644 --- a/src/main/java/org/apache/ibatis/executor/BatchExecutor.java +++ b/src/main/java/org/apache/ibatis/executor/BatchExecutor.java @@ -35,21 +35,26 @@ import org.apache.ibatis.transaction.Transaction; /** - * @author Jeff Butler + * @author Maozi Lao */ public class BatchExecutor extends BaseExecutor { public static final int BATCH_UPDATE_RETURN_VALUE = Integer.MIN_VALUE + 1002; + //JDBC Statement接口:其实现类有PreparedStatement,PreparedStatement private final List statementList = new ArrayList(); + //BatchResult主体是封装好的sql,这儿声明一个List主要是为了sql的复用 private final List batchResultList = new ArrayList(); + //executor当前的sql private String currentSql; private MappedStatement currentStatement; + //BatchExecutor也支持事务 public BatchExecutor(Configuration configuration, Transaction transaction) { super(configuration, transaction); } + //为父类BaseExecutor中的doUpdate()方法的批量实现 @Override public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException { final Configuration configuration = ms.getConfiguration(); @@ -57,12 +62,14 @@ public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLExcept 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); BatchResult batchResult = batchResultList.get(last); batchResult.addParameterObject(parameterObject); } else { + //如果没有当前sql对应的Statement,创建一个Statement并添加到batchResultList,方便下次复用 Connection connection = getConnection(ms.getStatementLog()); stmt = handler.prepare(connection); currentSql = sql; @@ -70,39 +77,50 @@ public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLExcept statementList.add(stmt); batchResultList.add(new BatchResult(ms, sql, parameterObject)); } + //给每个Statement设置参数 handler.parameterize(stmt); + //调用Statement.batch()方法,批量更新 handler.batch(stmt); return BATCH_UPDATE_RETURN_VALUE; } + //查询方法 @Override public List doQuery(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) - throws SQLException { + throws SQLException { Statement stmt = null; try { + //调用父类BaseExcutor的flushStatements()的方法执行BatchExecutor中doFlushStatements()方法 flushStatements(); Configuration configuration = ms.getConfiguration(); StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameterObject, rowBounds, resultHandler, boundSql); Connection connection = getConnection(ms.getStatementLog()); stmt = handler.prepare(connection); + //设置参数 handler.parameterize(stmt); + //查询方法,并将查询到的结果交给resultHandler封装 return handler.query(stmt, resultHandler); } finally { closeStatement(stmt); } } + //实现父类BaseExcutor的静态方法 @Override public List doFlushStatements(boolean isRollback) throws SQLException { try { List results = new ArrayList(); if (isRollback) { + //如果调用了父类BaseExecutor中回滚方法,会清空要执行的sql语句 return Collections.emptyList(); } for (int i = 0, n = statementList.size(); i < n; i++) { Statement stmt = statementList.get(i); BatchResult batchResult = batchResultList.get(i); try { + //对多个Statement的查询结果进行拦截,并设置返回的主键 + //注:BatchExecutor的doQuery()不会执行此逻辑 查询时不存在sql语句复用 此时statementList为空 + //反而是对doUpdate()方法进行了拦截,如果是对数据库进行批量添加,这里能够往bean中自动注入主键 batchResult.setUpdateCounts(stmt.executeBatch()); MappedStatement ms = batchResult.getMappedStatement(); List parameterObjects = batchResult.getParameterObjects(); @@ -118,14 +136,14 @@ public List doFlushStatements(boolean isRollback) throws SQLExcepti } catch (BatchUpdateException e) { StringBuilder message = new StringBuilder(); message.append(batchResult.getMappedStatement().getId()) - .append(" (batch index #") - .append(i + 1) - .append(")") - .append(" failed."); + .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."); + .append(i) + .append(" prior sub executor(s) completed successfully, but will be rolled back."); } throw new BatchExecutorException(message.toString(), e, results, batchResult); } From 3f32c15c2253c71801df41e00f41893870013fcd Mon Sep 17 00:00:00 2001 From: mao-pc <2261744549@qq.com> Date: Tue, 26 May 2020 16:52:35 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/org/apache/ibatis/executor/BatchExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/apache/ibatis/executor/BatchExecutor.java b/src/main/java/org/apache/ibatis/executor/BatchExecutor.java index f64702e1ae..85822f3f87 100644 --- a/src/main/java/org/apache/ibatis/executor/BatchExecutor.java +++ b/src/main/java/org/apache/ibatis/executor/BatchExecutor.java @@ -35,7 +35,7 @@ import org.apache.ibatis.transaction.Transaction; /** - * @author Maozi Lao + * @author Jeff Butler */ public class BatchExecutor extends BaseExecutor {