Skip to content

Instantly share code, notes, and snippets.

@oehme
Created January 12, 2012 11:12
Show Gist options
  • Save oehme/1599923 to your computer and use it in GitHub Desktop.
Save oehme/1599923 to your computer and use it in GitHub Desktop.
Alternating batched statements in myBatis
package org.apache.ibatis.executor;
import java.sql.BatchUpdateException;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.Transaction;
public class BatchExecutor extends BaseExecutor {
private static class BatchInfo {
private List<BatchResult> objResultList;
private List<Statement> objStmtList;
public BatchInfo(List<Statement> argStatementList,
List<BatchResult> argBatchResultList) {
objStmtList = argStatementList;
objResultList = argBatchResultList;
}
public List<BatchResult> getResults() {
return objResultList;
}
public List<Statement> getStatements() {
return objStmtList;
}
}
public static final int BATCH_UPDATE_RETURN_VALUE = Integer.MIN_VALUE + 1002;
private Map<String, BatchInfo> objBatchMap = new HashMap<String, BatchInfo>();
public BatchExecutor(Configuration argConfiguration,
Transaction argTransaction) {
super(argConfiguration, argTransaction);
}
@Override
public int doUpdate(MappedStatement argMs, Object argParameterObject)
throws SQLException {
Configuration varConfiguration = argMs.getConfiguration();
StatementHandler varHandler = varConfiguration.newStatementHandler(
this, argMs, argParameterObject, RowBounds.DEFAULT, null);
BoundSql varBoundSql = varHandler.getBoundSql();
String varSql = varBoundSql.getSql();
Statement varStmt;
if (objBatchMap.containsKey(varSql)) {
List<Statement> varStatementList = objBatchMap.get(varSql)
.getStatements();
int varLast = varStatementList.size() - 1;
varStmt = varStatementList.get(varLast);
} else {
Connection varConnection = transaction.getConnection();
varStmt = varHandler.prepare(varConnection);
ArrayList<Statement> varStatementList = new ArrayList<Statement>();
varStatementList.add(varStmt);
ArrayList<BatchResult> varBatchResultList = new ArrayList<BatchResult>();
varBatchResultList.add(new BatchResult(argMs, varSql,
argParameterObject));
objBatchMap.put(varSql, new BatchInfo(varStatementList,
varBatchResultList));
}
varHandler.parameterize(varStmt);
varHandler.batch(varStmt);
return BATCH_UPDATE_RETURN_VALUE;
}
@Override
public List<?> doQuery(MappedStatement argMs, Object argParameterObject,
RowBounds argRowBounds, ResultHandler argResultHandler)
throws SQLException {
Statement varStmt = null;
try {
flushStatements();
Configuration varConfiguration = argMs.getConfiguration();
StatementHandler varHandler = varConfiguration.newStatementHandler(
this, argMs, argParameterObject, argRowBounds,
argResultHandler);
Connection varConnection = transaction.getConnection();
varStmt = varHandler.prepare(varConnection);
varHandler.parameterize(varStmt);
return varHandler.query(varStmt, argResultHandler);
} finally {
closeStatement(varStmt);
}
}
@Override
public List<BatchResult> doFlushStatements(boolean argIsRollback)
throws SQLException {
try {
List<BatchResult> varResults = new ArrayList<BatchResult>();
if (argIsRollback) {
return Collections.emptyList();
} else {
for (BatchInfo varBatchInfo : objBatchMap.values()) {
List<Statement> varStatements = varBatchInfo
.getStatements();
List<BatchResult> varBatchResults = varBatchInfo
.getResults();
for (int i = 0, varSize = varStatements.size(); i < varSize; i++) {
Statement varStmt = varStatements.get(i);
BatchResult varBatchResult = varBatchResults.get(i);
try {
varBatchResult.setUpdateCounts(varStmt
.executeBatch());
MappedStatement varMs = varBatchResult
.getMappedStatement();
Object varParameter = varBatchResult
.getParameterObject();
KeyGenerator varKeyGenerator = varMs
.getKeyGenerator();
if (varKeyGenerator instanceof Jdbc3KeyGenerator) {
varKeyGenerator.processAfter(this, varMs,
varStmt, varParameter);
}
} catch (BatchUpdateException e) {
StringBuffer varMessage = new StringBuffer();
varMessage
.append(varBatchResult.getMappedStatement()
.getId()).append(" (batch index #")
.append(i + 1).append(")")
.append(" failed.");
if (i > 0) {
varMessage
.append(" ")
.append(i)
.append(" prior sub executor(s) completed successfully, but will be rolled back.");
}
throw new BatchExecutorException(
varMessage.toString(), e, varResults,
varBatchResult);
}
varResults.add(varBatchResult);
}
}
return varResults;
}
} finally {
closeStatements();
}
}
private void closeStatements() {
for (BatchInfo varBatchInfo : objBatchMap.values()) {
for (Statement varStmt : varBatchInfo.getStatements()) {
closeStatement(varStmt);
}
}
objBatchMap.clear();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment