8 changed files with 292 additions and 172 deletions
@ -0,0 +1,68 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2002-2008 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.springframework.jdbc.core; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
import java.sql.PreparedStatement; |
||||||
|
import java.sql.SQLException; |
||||||
|
|
||||||
|
/** |
||||||
|
* Generic utility methods for working with JDBC batch statements. Mainly for internal use |
||||||
|
* within the framework. |
||||||
|
* |
||||||
|
* @author Thomas Risberg |
||||||
|
*/ |
||||||
|
public abstract class BatchUpdateUtils { |
||||||
|
|
||||||
|
public static int[] executeBatchUpdate(String sql, final List<Object[]> batchValues, final int[] columnTypes, JdbcOperations jdbcOperations) { |
||||||
|
return jdbcOperations.batchUpdate( |
||||||
|
sql, |
||||||
|
new BatchPreparedStatementSetter() { |
||||||
|
|
||||||
|
public void setValues(PreparedStatement ps, int i) throws SQLException { |
||||||
|
Object[] values = batchValues.get(i); |
||||||
|
setStatementParameters(values, ps, columnTypes); |
||||||
|
} |
||||||
|
|
||||||
|
public int getBatchSize() { |
||||||
|
return batchValues.size(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
protected static void setStatementParameters(Object[] values, PreparedStatement ps, int[] columnTypes) throws SQLException { |
||||||
|
int colIndex = 0; |
||||||
|
for (Object value : values) { |
||||||
|
colIndex++; |
||||||
|
if (value instanceof SqlParameterValue) { |
||||||
|
SqlParameterValue paramValue = (SqlParameterValue) value; |
||||||
|
StatementCreatorUtils.setParameterValue(ps, colIndex, paramValue, paramValue.getValue()); |
||||||
|
} |
||||||
|
else { |
||||||
|
int colType; |
||||||
|
if (columnTypes == null || columnTypes.length < colIndex) { |
||||||
|
colType = SqlTypeValue.TYPE_UNKNOWN; |
||||||
|
} |
||||||
|
else { |
||||||
|
colType = columnTypes[colIndex - 1]; |
||||||
|
} |
||||||
|
StatementCreatorUtils.setParameterValue(ps, colIndex, colType, value); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,40 @@ |
|||||||
|
package org.springframework.jdbc.core.namedparam; |
||||||
|
|
||||||
|
import java.sql.PreparedStatement; |
||||||
|
import java.sql.SQLException; |
||||||
|
|
||||||
|
import org.springframework.jdbc.core.BatchUpdateUtils; |
||||||
|
import org.springframework.jdbc.core.JdbcOperations; |
||||||
|
import org.springframework.jdbc.core.BatchPreparedStatementSetter; |
||||||
|
|
||||||
|
/** |
||||||
|
* Generic utility methods for working with JDBC batch statements. Mainly for internal use |
||||||
|
* within the framework. |
||||||
|
* |
||||||
|
* @author Thomas Risberg |
||||||
|
*/ |
||||||
|
public class NamedParameterBatchUpdateUtils extends BatchUpdateUtils { |
||||||
|
|
||||||
|
public static int[] executeBatchUpdateWithNamedParameters(String sql, final SqlParameterSource[] batchArgs, JdbcOperations jdbcOperations) { |
||||||
|
if (batchArgs.length <= 0) { |
||||||
|
return new int[] {0}; |
||||||
|
} |
||||||
|
final ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql); |
||||||
|
String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, batchArgs[0]); |
||||||
|
return jdbcOperations.batchUpdate( |
||||||
|
sqlToUse, |
||||||
|
new BatchPreparedStatementSetter() { |
||||||
|
|
||||||
|
public void setValues(PreparedStatement ps, int i) throws SQLException { |
||||||
|
Object[] values = NamedParameterUtils.buildValueArray(parsedSql, batchArgs[i], null); |
||||||
|
int[] columnTypes = NamedParameterUtils.buildSqlTypeArray(parsedSql, batchArgs[i]); |
||||||
|
setStatementParameters(values, ps, columnTypes); |
||||||
|
} |
||||||
|
|
||||||
|
public int getBatchSize() { |
||||||
|
return batchArgs.length; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,90 @@ |
|||||||
|
package org.springframework.jdbc.core; |
||||||
|
|
||||||
|
import java.sql.Connection; |
||||||
|
import java.sql.PreparedStatement; |
||||||
|
import java.sql.DatabaseMetaData; |
||||||
|
import java.sql.SQLException; |
||||||
|
import java.util.List; |
||||||
|
import javax.sql.DataSource; |
||||||
|
|
||||||
|
import org.easymock.MockControl; |
||||||
|
import org.apache.commons.logging.LogFactory; |
||||||
|
|
||||||
|
import org.springframework.jdbc.core.namedparam.SqlParameterSource; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Thomas Risberg |
||||||
|
*/ |
||||||
|
public abstract class BatchUpdateTestHelper { |
||||||
|
|
||||||
|
public static void prepareBatchUpdateMocks(String sqlToUse, Object ids, |
||||||
|
int[] rowsAffected, |
||||||
|
MockControl ctrlDataSource, DataSource mockDataSource, MockControl ctrlConnection, Connection mockConnection, |
||||||
|
MockControl ctrlPreparedStatement, |
||||||
|
PreparedStatement mockPreparedStatement, MockControl ctrlDatabaseMetaData, DatabaseMetaData mockDatabaseMetaData) |
||||||
|
throws SQLException { |
||||||
|
mockConnection.getMetaData(); |
||||||
|
ctrlConnection.setDefaultReturnValue(null); |
||||||
|
mockConnection.close(); |
||||||
|
ctrlConnection.setDefaultVoidCallable(); |
||||||
|
|
||||||
|
mockDataSource.getConnection(); |
||||||
|
ctrlDataSource.setDefaultReturnValue(mockConnection); |
||||||
|
|
||||||
|
mockPreparedStatement.getConnection(); |
||||||
|
ctrlPreparedStatement.setReturnValue(mockConnection); |
||||||
|
int idLength = 0; |
||||||
|
if (ids instanceof SqlParameterSource[]) { |
||||||
|
idLength = ((SqlParameterSource[])ids).length; |
||||||
|
} |
||||||
|
else { |
||||||
|
idLength = ((List)ids).size(); |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < idLength; i++) { |
||||||
|
if (ids instanceof SqlParameterSource[]) { |
||||||
|
mockPreparedStatement.setObject(1, ((SqlParameterSource[])ids)[i].getValue("id")); |
||||||
|
} |
||||||
|
else { |
||||||
|
mockPreparedStatement.setObject(1, ((Object[])((List)ids).get(i))[0]); |
||||||
|
} |
||||||
|
ctrlPreparedStatement.setVoidCallable(); |
||||||
|
mockPreparedStatement.addBatch(); |
||||||
|
ctrlPreparedStatement.setVoidCallable(); |
||||||
|
} |
||||||
|
mockPreparedStatement.executeBatch(); |
||||||
|
ctrlPreparedStatement.setReturnValue(rowsAffected); |
||||||
|
if (LogFactory.getLog(JdbcTemplate.class).isDebugEnabled()) { |
||||||
|
mockPreparedStatement.getWarnings(); |
||||||
|
ctrlPreparedStatement.setReturnValue(null); |
||||||
|
} |
||||||
|
mockPreparedStatement.close(); |
||||||
|
ctrlPreparedStatement.setVoidCallable(); |
||||||
|
|
||||||
|
mockDatabaseMetaData.getDatabaseProductName(); |
||||||
|
ctrlDatabaseMetaData.setReturnValue("MySQL"); |
||||||
|
mockDatabaseMetaData.supportsBatchUpdates(); |
||||||
|
ctrlDatabaseMetaData.setReturnValue(true); |
||||||
|
|
||||||
|
mockConnection.prepareStatement(sqlToUse); |
||||||
|
ctrlConnection.setReturnValue(mockPreparedStatement); |
||||||
|
mockConnection.getMetaData(); |
||||||
|
ctrlConnection.setReturnValue(mockDatabaseMetaData, 2); |
||||||
|
} |
||||||
|
|
||||||
|
public static void replayBatchUpdateMocks(MockControl ctrlDataSource, |
||||||
|
MockControl ctrlConnection, |
||||||
|
MockControl ctrlPreparedStatement, |
||||||
|
MockControl ctrlDatabaseMetaData) { |
||||||
|
ctrlPreparedStatement.replay(); |
||||||
|
ctrlDatabaseMetaData.replay(); |
||||||
|
ctrlDataSource.replay(); |
||||||
|
ctrlConnection.replay(); |
||||||
|
} |
||||||
|
|
||||||
|
public static void verifyBatchUpdateMocks(MockControl ctrlPreparedStatement, MockControl ctrlDatabaseMetaData) { |
||||||
|
ctrlPreparedStatement.verify(); |
||||||
|
ctrlDatabaseMetaData.verify(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue