Merge pull request #132 from mminella/BATCH-1955
BATCH-1955: Removed requirement to inject ItemSqlParamterSourceProvider ...
This commit is contained in:
@@ -19,6 +19,7 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
@@ -55,6 +56,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Thomas Risberg
|
||||
* @author Michael Minella
|
||||
* @since 2.0
|
||||
*/
|
||||
public class JdbcBatchItemWriter<T> implements ItemWriter<T>, InitializingBean {
|
||||
@@ -106,7 +108,8 @@ public class JdbcBatchItemWriter<T> implements ItemWriter<T>, InitializingBean {
|
||||
/**
|
||||
* Public setter for the {@link ItemSqlParameterSourceProvider}.
|
||||
* @param itemSqlParameterSourceProvider the {@link ItemSqlParameterSourceProvider} to
|
||||
* set. This is required when using named parameters for the SQL statement.
|
||||
* set. This is required when using named parameters for the SQL statement and the type
|
||||
* to be written does not implement {@link Map}.
|
||||
*/
|
||||
public void setItemSqlParameterSourceProvider(ItemSqlParameterSourceProvider<T> itemSqlParameterSourceProvider) {
|
||||
this.itemSqlParameterSourceProvider = itemSqlParameterSourceProvider;
|
||||
@@ -147,10 +150,7 @@ public class JdbcBatchItemWriter<T> implements ItemWriter<T>, InitializingBean {
|
||||
}
|
||||
usingNamedParameters = true;
|
||||
}
|
||||
if (usingNamedParameters) {
|
||||
Assert.notNull(itemSqlParameterSourceProvider, "Using SQL statement with named parameters requires an ItemSqlParameterSourceProvider");
|
||||
}
|
||||
else {
|
||||
if (!usingNamedParameters) {
|
||||
Assert.notNull(itemPreparedStatementSetter, "Using SQL statement with '?' placeholders requires an ItemPreparedStatementSetter");
|
||||
}
|
||||
}
|
||||
@@ -159,6 +159,7 @@ public class JdbcBatchItemWriter<T> implements ItemWriter<T>, InitializingBean {
|
||||
* @see org.springframework.batch.item.ItemWriter#write(java.util.List)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public void write(final List<? extends T> items) throws Exception {
|
||||
|
||||
if (!items.isEmpty()) {
|
||||
@@ -170,12 +171,16 @@ public class JdbcBatchItemWriter<T> implements ItemWriter<T>, InitializingBean {
|
||||
int[] updateCounts = null;
|
||||
|
||||
if (usingNamedParameters) {
|
||||
SqlParameterSource[] batchArgs = new SqlParameterSource[items.size()];
|
||||
int i = 0;
|
||||
for (T item : items) {
|
||||
batchArgs[i++] = itemSqlParameterSourceProvider.createSqlParameterSource(item);
|
||||
if(items.get(0) instanceof Map) {
|
||||
updateCounts = namedParameterJdbcTemplate.batchUpdate(sql, items.toArray(new Map[0]));
|
||||
} else {
|
||||
SqlParameterSource[] batchArgs = new SqlParameterSource[items.size()];
|
||||
int i = 0;
|
||||
for (T item : items) {
|
||||
batchArgs[i++] = itemSqlParameterSourceProvider.createSqlParameterSource(item);
|
||||
}
|
||||
updateCounts = namedParameterJdbcTemplate.batchUpdate(sql, batchArgs);
|
||||
}
|
||||
updateCounts = namedParameterJdbcTemplate.batchUpdate(sql, batchArgs);
|
||||
}
|
||||
else {
|
||||
updateCounts = (int[]) namedParameterJdbcTemplate.getJdbcOperations().execute(sql, new PreparedStatementCallback() {
|
||||
|
||||
@@ -24,11 +24,14 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.BaseMatcher;
|
||||
import org.hamcrest.Description;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
@@ -37,13 +40,15 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||
/**
|
||||
* @author Thomas Risberg
|
||||
* @author Will Schipp
|
||||
* @author Michael Minella
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "serial", "unchecked"})
|
||||
public class JdbcBatchItemWriterNamedParameterTests {
|
||||
|
||||
private JdbcBatchItemWriter<Foo> writer = new JdbcBatchItemWriter<Foo>();
|
||||
private JdbcBatchItemWriter writer = new JdbcBatchItemWriter<Foo>();
|
||||
|
||||
private NamedParameterJdbcOperations namedParameterJdbcOperations;
|
||||
|
||||
private NamedParameterJdbcOperations namedParameterJdbcOperations;
|
||||
|
||||
private String sql = "update foo set bar = :bar where id = :id";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@@ -55,7 +60,7 @@ public class JdbcBatchItemWriterNamedParameterTests {
|
||||
this.id = 1L;
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -71,12 +76,12 @@ public class JdbcBatchItemWriterNamedParameterTests {
|
||||
public void setBar(String bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
namedParameterJdbcOperations = mock(NamedParameterJdbcOperations.class);
|
||||
namedParameterJdbcOperations = mock(NamedParameterJdbcOperations.class);
|
||||
writer.setSql(sql);
|
||||
writer.setJdbcTemplate(namedParameterJdbcOperations);
|
||||
writer.setItemSqlParameterSourceProvider(
|
||||
@@ -113,22 +118,27 @@ public class JdbcBatchItemWriterNamedParameterTests {
|
||||
assertTrue("Message does not contain 'sql'.", message.indexOf("sql") >= 0);
|
||||
}
|
||||
writer.setSql("select * from foo where id = :id");
|
||||
try {
|
||||
writer.afterPropertiesSet();
|
||||
fail("Expected IllegalArgumentException");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
// expected
|
||||
String message = e.getMessage();
|
||||
assertTrue("Message does not contain 'ItemSqlParameterSourceProvider'.", message.indexOf("ItemSqlParameterSourceProvider") >= 0);
|
||||
}
|
||||
writer.setItemSqlParameterSourceProvider(
|
||||
new BeanPropertyItemSqlParameterSourceProvider<Foo>());
|
||||
|
||||
writer.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteAndFlush() throws Exception {
|
||||
writer.setItemSqlParameterSourceProvider(null);
|
||||
ArgumentCaptor<Map []> captor = ArgumentCaptor.forClass(Map[].class);
|
||||
|
||||
when(namedParameterJdbcOperations.batchUpdate(eq(sql),
|
||||
captor.capture()))
|
||||
.thenReturn(new int[] {1});
|
||||
writer.write(Collections.singletonList(new HashMap<String, Object>() {{put("foo", "bar");}}));
|
||||
|
||||
assertEquals(1, captor.getValue().length);
|
||||
Map<String, Object> results = captor.getValue()[0];
|
||||
assertEquals("bar", results.get("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteAndFlushMap() throws Exception {
|
||||
when(namedParameterJdbcOperations.batchUpdate(eq(sql),
|
||||
eqSqlParameterSourceArray(new SqlParameterSource[] {new BeanPropertySqlParameterSource(new Foo("bar"))})))
|
||||
.thenReturn(new int[] {1});
|
||||
@@ -168,42 +178,42 @@ public class JdbcBatchItemWriterNamedParameterTests {
|
||||
|
||||
public static SqlParameterSource[] eqSqlParameterSourceArray(SqlParameterSource[] in) {
|
||||
argThat(new SqlParameterSourceArrayEquals(in));
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class SqlParameterSourceArrayEquals extends BaseMatcher<SqlParameterSource[]> {
|
||||
private SqlParameterSource[] expected;
|
||||
private SqlParameterSource[] expected;
|
||||
|
||||
public SqlParameterSourceArrayEquals(SqlParameterSource[] expected) {
|
||||
this.expected = expected;
|
||||
}
|
||||
public SqlParameterSourceArrayEquals(SqlParameterSource[] expected) {
|
||||
this.expected = expected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object actual) {
|
||||
if (!(actual instanceof SqlParameterSource[])) {
|
||||
return false;
|
||||
}
|
||||
SqlParameterSource[] actualArray = (SqlParameterSource[])actual;
|
||||
if (expected.length != actualArray.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < expected.length; i++) {
|
||||
if (!expected[i].getClass().equals(actualArray[i].getClass())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean matches(Object actual) {
|
||||
if (!(actual instanceof SqlParameterSource[])) {
|
||||
return false;
|
||||
}
|
||||
SqlParameterSource[] actualArray = (SqlParameterSource[])actual;
|
||||
if (expected.length != actualArray.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < expected.length; i++) {
|
||||
if (!expected[i].getClass().equals(actualArray[i].getClass())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText("eqSqlParameterSourceArray(");
|
||||
description.appendText("eqSqlParameterSourceArray(");
|
||||
description.appendText(expected.getClass().getName());
|
||||
description.appendText(" with length \"");
|
||||
description.appendValue(expected.length);
|
||||
description.appendText("\")");
|
||||
description.appendText("\")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user