added batchUpdate methods to NamedParameterJdbcTemplate (SPR-3322)

This commit is contained in:
Thomas Risberg
2009-05-28 03:15:47 +00:00
parent 88e32a3cfe
commit 4105957596
8 changed files with 292 additions and 172 deletions

View File

@@ -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();
}
}

View File

@@ -20,6 +20,8 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -40,6 +42,7 @@ import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlParameterValue;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.BatchUpdateTestHelper;
/**
* @author Rick Evans
@@ -410,4 +413,41 @@ public class NamedParameterJdbcTemplateTests extends AbstractJdbcTests {
assertTrue("Customer forename was assigned correctly", cust.getForename().equals("rod"));
}
public void testBatchUpdateWithSqlParameterSource() throws Exception {
final String sqlToUse = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id";
final SqlParameterSource[] ids = new SqlParameterSource[2];
ids[0] = new MapSqlParameterSource("id", 100);
ids[1] = new MapSqlParameterSource("id", 200);
final int[] rowsAffected = new int[] { 1, 2 };
MockControl ctrlDataSource = MockControl.createControl(DataSource.class);
DataSource mockDataSource = (DataSource) ctrlDataSource.getMock();
MockControl ctrlConnection = MockControl.createControl(Connection.class);
Connection mockConnection = (Connection) ctrlConnection.getMock();
MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class);
DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock();
BatchUpdateTestHelper.prepareBatchUpdateMocks(sqlToUse, ids, rowsAffected, ctrlDataSource, mockDataSource, ctrlConnection,
mockConnection, ctrlPreparedStatement, mockPreparedStatement, ctrlDatabaseMetaData,
mockDatabaseMetaData);
BatchUpdateTestHelper.replayBatchUpdateMocks(ctrlDataSource, ctrlConnection, ctrlPreparedStatement, ctrlDatabaseMetaData);
JdbcTemplate template = new JdbcTemplate(mockDataSource, false);
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(template);
int[] actualRowsAffected = namedParameterJdbcTemplate.batchUpdate(sql, ids);
assertTrue("executed 2 updates", actualRowsAffected.length == 2);
assertEquals(rowsAffected[0], actualRowsAffected[0]);
assertEquals(rowsAffected[1], actualRowsAffected[1]);
BatchUpdateTestHelper.verifyBatchUpdateMocks(ctrlPreparedStatement, ctrlDatabaseMetaData);
}
}

View File

@@ -38,6 +38,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.BatchUpdateTestHelper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
@@ -522,22 +523,6 @@ public class SimpleJdbcTemplateTests extends TestCase {
}
public void testBatchUpdateWithSqlParameterSource() throws Exception {
MockControl ctrlDataSource;
DataSource mockDataSource;
MockControl ctrlConnection;
Connection mockConnection;
ctrlConnection = MockControl.createControl(Connection.class);
mockConnection = (Connection) ctrlConnection.getMock();
mockConnection.getMetaData();
ctrlConnection.setDefaultReturnValue(null);
mockConnection.close();
ctrlConnection.setDefaultVoidCallable();
ctrlDataSource = MockControl.createControl(DataSource.class);
mockDataSource = (DataSource) ctrlDataSource.getMock();
mockDataSource.getConnection();
ctrlDataSource.setDefaultReturnValue(mockConnection);
final String sqlToUse = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = :id";
@@ -546,44 +531,20 @@ public class SimpleJdbcTemplateTests extends TestCase {
ids[1] = new MapSqlParameterSource("id", 200);
final int[] rowsAffected = new int[] { 1, 2 };
MockControl ctrlDataSource = MockControl.createControl(DataSource.class);
DataSource mockDataSource = (DataSource) ctrlDataSource.getMock();
MockControl ctrlConnection = MockControl.createControl(Connection.class);
Connection mockConnection = (Connection) ctrlConnection.getMock();
MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
mockPreparedStatement.getConnection();
ctrlPreparedStatement.setReturnValue(mockConnection);
mockPreparedStatement.setObject(1, ((Integer)ids[0].getValue("id")).intValue());
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.addBatch();
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.setObject(1, ((Integer)ids[1].getValue("id")).intValue());
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.addBatch();
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.executeBatch();
ctrlPreparedStatement.setReturnValue(rowsAffected);
if (debugEnabled) {
mockPreparedStatement.getWarnings();
ctrlPreparedStatement.setReturnValue(null);
}
mockPreparedStatement.close();
ctrlPreparedStatement.setVoidCallable();
MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class);
DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock();
mockDatabaseMetaData.getDatabaseProductName();
ctrlDatabaseMetaData.setReturnValue("MySQL");
mockDatabaseMetaData.supportsBatchUpdates();
ctrlDatabaseMetaData.setReturnValue(true);
mockConnection.prepareStatement(sqlToUse);
ctrlConnection.setReturnValue(mockPreparedStatement);
mockConnection.getMetaData();
ctrlConnection.setReturnValue(mockDatabaseMetaData, 2);
BatchUpdateTestHelper.prepareBatchUpdateMocks(sqlToUse, ids, rowsAffected, ctrlDataSource, mockDataSource, ctrlConnection,
mockConnection, ctrlPreparedStatement, mockPreparedStatement, ctrlDatabaseMetaData,
mockDatabaseMetaData);
ctrlPreparedStatement.replay();
ctrlDatabaseMetaData.replay();
ctrlDataSource.replay();
ctrlConnection.replay();
BatchUpdateTestHelper.replayBatchUpdateMocks(ctrlDataSource, ctrlConnection, ctrlPreparedStatement, ctrlDatabaseMetaData);
JdbcTemplate template = new JdbcTemplate(mockDataSource, false);
SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(template);
@@ -594,27 +555,10 @@ public class SimpleJdbcTemplateTests extends TestCase {
assertEquals(rowsAffected[0], actualRowsAffected[0]);
assertEquals(rowsAffected[1], actualRowsAffected[1]);
ctrlPreparedStatement.verify();
ctrlDatabaseMetaData.verify();
BatchUpdateTestHelper.verifyBatchUpdateMocks(ctrlPreparedStatement, ctrlDatabaseMetaData);
}
public void testBatchUpdateWithListOfObjectArrays() throws Exception {
MockControl ctrlDataSource;
DataSource mockDataSource;
MockControl ctrlConnection;
Connection mockConnection;
ctrlConnection = MockControl.createControl(Connection.class);
mockConnection = (Connection) ctrlConnection.getMock();
mockConnection.getMetaData();
ctrlConnection.setDefaultReturnValue(null);
mockConnection.close();
ctrlConnection.setDefaultVoidCallable();
ctrlDataSource = MockControl.createControl(DataSource.class);
mockDataSource = (DataSource) ctrlDataSource.getMock();
mockDataSource.getConnection();
ctrlDataSource.setDefaultReturnValue(mockConnection);
final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
final List<Object[]> ids = new ArrayList<Object[]>();
@@ -622,44 +566,20 @@ public class SimpleJdbcTemplateTests extends TestCase {
ids.add(new Object[] {200});
final int[] rowsAffected = new int[] { 1, 2 };
MockControl ctrlDataSource = MockControl.createControl(DataSource.class);
DataSource mockDataSource = (DataSource) ctrlDataSource.getMock();
MockControl ctrlConnection = MockControl.createControl(Connection.class);
Connection mockConnection = (Connection) ctrlConnection.getMock();
MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
mockPreparedStatement.getConnection();
ctrlPreparedStatement.setReturnValue(mockConnection);
mockPreparedStatement.setObject(1, ((Integer)ids.get(0)[0]).intValue());
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.addBatch();
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.setObject(1, ((Integer)ids.get(1)[0]).intValue());
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.addBatch();
ctrlPreparedStatement.setVoidCallable();
mockPreparedStatement.executeBatch();
ctrlPreparedStatement.setReturnValue(rowsAffected);
if (debugEnabled) {
mockPreparedStatement.getWarnings();
ctrlPreparedStatement.setReturnValue(null);
}
mockPreparedStatement.close();
ctrlPreparedStatement.setVoidCallable();
MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class);
DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock();
mockDatabaseMetaData.getDatabaseProductName();
ctrlDatabaseMetaData.setReturnValue("MySQL");
mockDatabaseMetaData.supportsBatchUpdates();
ctrlDatabaseMetaData.setReturnValue(true);
mockConnection.prepareStatement(sql);
ctrlConnection.setReturnValue(mockPreparedStatement);
mockConnection.getMetaData();
ctrlConnection.setReturnValue(mockDatabaseMetaData, 2);
BatchUpdateTestHelper.prepareBatchUpdateMocks(sql, ids, rowsAffected, ctrlDataSource, mockDataSource, ctrlConnection,
mockConnection, ctrlPreparedStatement, mockPreparedStatement, ctrlDatabaseMetaData,
mockDatabaseMetaData);
ctrlPreparedStatement.replay();
ctrlDatabaseMetaData.replay();
ctrlDataSource.replay();
ctrlConnection.replay();
BatchUpdateTestHelper.replayBatchUpdateMocks(ctrlDataSource, ctrlConnection, ctrlPreparedStatement, ctrlDatabaseMetaData);
JdbcTemplate template = new JdbcTemplate(mockDataSource, false);
SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(template);
@@ -670,8 +590,7 @@ public class SimpleJdbcTemplateTests extends TestCase {
assertEquals(rowsAffected[0], actualRowsAffected[0]);
assertEquals(rowsAffected[1], actualRowsAffected[1]);
ctrlPreparedStatement.verify();
ctrlDatabaseMetaData.verify();
BatchUpdateTestHelper.verifyBatchUpdateMocks(ctrlPreparedStatement, ctrlDatabaseMetaData);
}
}