Created
January 12, 2012 11:12
-
-
Save oehme/1599923 to your computer and use it in GitHub Desktop.
Alternating batched statements in myBatis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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