All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.ibatis.sqlmap.engine.execution.Batch Maven / Gradle / Ivy
Go to download
The jBATIS persistence framework will help you to significantly reduce the amount of Java code that you normally need to access a relational database. iBATIS simply maps JavaBeans to SQL statements using a very simple XML descriptor.
package com.ibatis.sqlmap.engine.execution;
import java.sql.BatchUpdateException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.ibatis.common.Objects;
import com.ibatis.common.jdbc.exception.NestedSQLException;
import com.ibatis.sqlmap.client.BatchResult;
import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
import com.ibatis.sqlmap.engine.mapping.statement.StatementType;
import com.ibatis.sqlmap.engine.scope.ErrorContext;
import com.ibatis.sqlmap.engine.scope.SessionScope;
import com.ibatis.sqlmap.engine.scope.StatementScope;
/**
* new Batch
*/
public class Batch {
final boolean debug;
private boolean cleanup;
private Map batchResultList = new LinkedHashMap();
private int totalSize;
private int totalRows;
final int batchSize;
private Map statementSqls = new HashMap();
@Override
public String toString() {
return "Batch total size: " + totalSize + ", total affected rows: " + totalRows + ", sql count: "
+ batchResultList.size();
}
public int getTotalRows() {
return totalRows;
}
/**
* Create a new batch
*/
public Batch(int batchSize, boolean debug) {
this.debug = debug;
this.batchSize = batchSize;
this.totalSize = 0;
}
/**
* Getter for the batch size
*
* @return - the batch size
*/
public int getSize() {
return totalSize;
}
public boolean isCleanup() {
return cleanup;
}
/**
* Add a prepared statement to the batch
*
* @param statementScope
* - the request scope
* @param conn
* - the database connection
* @param sql
* - the SQL to add
* @param parameters
* - the parameters for the SQL
* @return
* @throws SQLException
* - if the prepare for the SQL fails
*/
public void addBatch(StatementScope statementScope, Connection conn, String sql, Object[] parameters)
throws SQLException {
MappedStatement ms = statementScope.getStatement();
boolean isCall = ms.getStatementType() == StatementType.PROCEDURE;
statementSqls.put(ms, sql);
Object key = Objects.getKey(ms.getId(), sql);
BatchResult br = batchResultList.get(key);
if (br == null) {
br = new BatchResult(batchSize, sql, statementScope.getErrorContext());
batchResultList.put(key, br);
}
PreparedStatement ps = br.getPreparedStatement();
if (ps == null) {
if (isCall) {
ps = DefaultSqlExecutor.prepareCall(statementScope.getSession(), conn, sql);
} else {
ps = DefaultSqlExecutor.prepareStatement(statementScope.getSession(), conn, sql, false);
}
DefaultSqlExecutor.setStatementTimeout(ms, ps);
br.setPreparedStatement(ps);
}
Object[] args = statementScope.getParameterMap().setParameters(statementScope, ps, parameters);
ps.addBatch();
br.total++;
br.addArgs(args);
totalSize++;
}
/**
* Execute the current session's batch
*
* @return - the number of rows updated
* @throws SQLException
* - if the batch fails
*/
public int executeBatch() throws SQLException {
int totalRowCount = 0;
for (BatchResult br : batchResultList.values()) {
PreparedStatement ps = br.getPreparedStatement();
int[] rowCounts = null;
try {
rowCounts = ps.executeBatch();
} catch (BatchUpdateException e) {
ErrorContext ec = br.getErrorContext();
ec.setCause(e);
int[] uc = e.getUpdateCounts();
if (uc != null) {
if (uc.length == br.total) {
// the driver continues to process commands after an error
int i = 0;
for (; i < uc.length; i++) {
if (uc[i] == Statement.EXECUTE_FAILED) {
break;
}
}
ec.setArgs(br.getArgs(i));
ec.setBatchInfo("Batch failed at: " + (i + 1) + " of " + br.total);
} else {
ec.setArgs(br.getArgs(uc.length));
ec.setBatchInfo("Batch failed at: " + (uc.length + 1) + " of " + br.total);
}
} else {
// shit driver: no error index
ec.setArgs(br.getArgs(-1));
ec.setBatchInfo("Batch error: " + "total = " + br.total);
}
throw new NestedSQLException(ec.toString(), e.getSQLState(), e.getErrorCode(), e);
}
int rows = 0;
for (int j = 0; j < rowCounts.length; j++) {
if (rowCounts[j] == Statement.SUCCESS_NO_INFO) {
// do nothing
} else if (rowCounts[j] == Statement.EXECUTE_FAILED) {
ErrorContext ec = br.getErrorContext();
ec.setBatchInfo("Batch failed: " + (j + 1) + " of " + br.total);
ec.setArgs(br.getArgs(j));
ec.setCause("The batched statement: " + (j + 1) + " failed to execute.");
throw new SQLException(ec.toString());
} else {
rows += rowCounts[j];
totalRowCount += rowCounts[j];
}
}
br.totalRows = rows;
}
totalRows = totalRowCount;
return totalRowCount;
}
/**
* Batch execution method that returns all the information the driver has to offer.
*
* @return a List of BatchResult objects
* @throws BatchException
* (an SQLException sub class) if any nested batch fails
* @throws SQLException
* if a database access error occurs, or the drive does not support batch statements
* @throws BatchException
* if the driver throws BatchUpdateException
*/
public List executeBatchDetailed() throws SQLException, BatchException {
List answer = new ArrayList();
int totalRowCount = 0;
int i = 0;
for (BatchResult br : batchResultList.values()) {
PreparedStatement ps = br.getPreparedStatement();
try {
br.setUpdateCounts(ps.executeBatch());
} catch (BatchUpdateException e) {
ErrorContext ec = br.getErrorContext();
ec.setCause(e);
int[] uc = e.getUpdateCounts();
if (uc != null) {
if (uc.length == br.total) {
// the driver continues to process commands after an error
int j = 0;
for (; j < uc.length; j++) {
if (uc[i] == Statement.EXECUTE_FAILED) {
break;
}
}
ec.setArgs(br.getArgs(i));
ec.setBatchInfo("Batch(" + (i + 1) + ") failed at: " + (j + 1) + " of " + br.total);
} else {
ec.setArgs(br.getArgs(uc.length));
ec.setBatchInfo("Batch(" + (i + 1) + ") failed at: " + (uc.length + 1) + " of " + br.total);
}
} else {
ec.setArgs(br.getArgs(-1));
ec.setBatchInfo("Batch(" + (i + 1) + ") error: " + "total = " + br.total);
}
throw new BatchException(ec.toString(), e, answer, br.getStatementId(), br.getSql());
}
int rows = 0;
int[] rowCounts = br.getUpdateCounts();
for (int j = 0; j < rowCounts.length; j++) {
if (rowCounts[j] == Statement.SUCCESS_NO_INFO) {
// do nothing
} else if (rowCounts[j] == Statement.EXECUTE_FAILED) {
// do nothing
} else {
rows += rowCounts[j];
totalRowCount += rowCounts[j];
}
}
br.totalRows = rows;
answer.add(br);
i++;
}
totalRows = totalRowCount;
return answer;
}
public boolean hasNotifier(ExecuteNotifier en) {
return statementSqls != null && statementSqls.containsKey(en);
}
/**
* Close all the statements in the batch and clear all the statements
*
* @param sessionScope
*/
public void cleanupBatch(SessionScope sessionScope) {
this.cleanup = true;
for (BatchResult br : batchResultList.values()) {
DefaultSqlExecutor.closeStatement(sessionScope, br.getPreparedStatement());
br.setPreparedStatement(null);
}
if (!debug) {
batchResultList.clear();
}
if (statementSqls != null) {
Long timestamp = System.currentTimeMillis();
for (ExecuteNotifier en : statementSqls.keySet()) {
en.notifyListeners(timestamp);
}
if (!debug) {
statementSqls.clear();
statementSqls = null;
}
}
}
public List popErrorContexts() {
List list = new ArrayList();
for (BatchResult br : batchResultList.values()) {
ErrorContext ec = br.getErrorContext();
ec.setBatchInfo("Batch size: " + br.total + ", affected rows: " + br.totalRows);
ec.setArgs(br.getArgs(-1));
list.add(ec);
}
batchResultList.clear();
return list;
}
public Map popBatchedMap() {
Map ret = statementSqls;
statementSqls = null;
return ret;
}
}