SqlParameterSourceUtils.createBatch with Collection support

Issue: SPR-16215
This commit is contained in:
Juergen Hoeller 2017-11-19 21:17:24 +01:00
parent 20fcefc647
commit a8b48848b9
3 changed files with 54 additions and 33 deletions

View File

@ -23,8 +23,8 @@ import java.util.List;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
* Generic utility methods for working with JDBC batch statements. Mainly for internal use * Generic utility methods for working with JDBC batch statements.
* within the framework. * Mainly for internal use within the framework.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @since 3.0 * @since 3.0

View File

@ -337,13 +337,7 @@ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations
@Override @Override
public int[] batchUpdate(String sql, Map<String, ?>[] batchValues) { public int[] batchUpdate(String sql, Map<String, ?>[] batchValues) {
SqlParameterSource[] batchArgs = new SqlParameterSource[batchValues.length]; return batchUpdate(sql, SqlParameterSourceUtils.createBatch(batchValues));
int i = 0;
for (Map<String, ?> values : batchValues) {
batchArgs[i] = new MapSqlParameterSource(values);
i++;
}
return batchUpdate(sql, batchArgs);
} }
@Override @Override

View File

@ -16,6 +16,8 @@
package org.springframework.jdbc.core.namedparam; package org.springframework.jdbc.core.namedparam;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -23,47 +25,72 @@ import org.springframework.jdbc.core.SqlParameterValue;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
* Class that provides helper methods for the use of {@link SqlParameterSource} * Class that provides helper methods for the use of {@link SqlParameterSource},
* with {@code SimpleJdbc} classes. * in particular with {@link NamedParameterJdbcTemplate}.
* *
* @author Thomas Risberg * @author Thomas Risberg
* @author Juergen Hoeller
* @since 2.5 * @since 2.5
*/ */
public class SqlParameterSourceUtils { public abstract class SqlParameterSourceUtils {
/** /**
* Create an array of MapSqlParameterSource objects populated with data from the * Create an array of {@link SqlParameterSource} objects populated with data
* values passed in. This will define what is included in a batch operation. * from the values passed in (either a {@link Map} or a bean object).
* @param valueMaps array of Maps containing the values to be used * This will define what is included in a batch operation.
* @return an array of SqlParameterSource * @param candidates object array of objects containing the values to be used
* @return an array of {@link SqlParameterSource}
* @see MapSqlParameterSource
* @see BeanPropertySqlParameterSource
* @see NamedParameterJdbcTemplate#batchUpdate(String, SqlParameterSource[]))
*/ */
public static SqlParameterSource[] createBatch(Map<String, ?>[] valueMaps) { @SuppressWarnings("unchecked")
MapSqlParameterSource[] batch = new MapSqlParameterSource[valueMaps.length]; public static SqlParameterSource[] createBatch(Object... candidates) {
for (int i = 0; i < valueMaps.length; i++) { return createBatch(Arrays.asList(candidates));
Map<String, ?> valueMap = valueMaps[i]; }
batch[i] = new MapSqlParameterSource(valueMap);
/**
* Create an array of {@link SqlParameterSource} objects populated with data
* from the values passed in (either a {@link Map} or a bean object).
* This will define what is included in a batch operation.
* @param candidates collection of objects containing the values to be used
* @return an array of {@link SqlParameterSource}
* @since 5.0.2
* @see MapSqlParameterSource
* @see BeanPropertySqlParameterSource
* @see NamedParameterJdbcTemplate#batchUpdate(String, SqlParameterSource[]))
*/
@SuppressWarnings("unchecked")
public static SqlParameterSource[] createBatch(Collection<?> candidates) {
SqlParameterSource[] batch = new SqlParameterSource[candidates.size()];
int i = 0;
for (Object candidate : candidates) {
batch[i] = (candidate instanceof Map ? new MapSqlParameterSource((Map<String, ?>) candidate) :
new BeanPropertySqlParameterSource(candidate));
i++;
} }
return batch; return batch;
} }
/** /**
* Create an array of BeanPropertySqlParameterSource objects populated with data * Create an array of {@link MapSqlParameterSource} objects populated with data from
* from the values passed in. This will define what is included in a batch operation. * the values passed in. This will define what is included in a batch operation.
* @param beans object array of beans containing the values to be used * @param valueMaps array of {@link Map} instances containing the values to be used
* @return an array of SqlParameterSource * @return an array of {@link SqlParameterSource}
* @see MapSqlParameterSource
* @see NamedParameterJdbcTemplate#batchUpdate(String, Map[])
*/ */
public static SqlParameterSource[] createBatch(Object[] beans) { public static SqlParameterSource[] createBatch(Map<String, ?>[] valueMaps) {
BeanPropertySqlParameterSource[] batch = new BeanPropertySqlParameterSource[beans.length]; SqlParameterSource[] batch = new SqlParameterSource[valueMaps.length];
for (int i = 0; i < beans.length; i++) { for (int i = 0; i < valueMaps.length; i++) {
Object bean = beans[i]; batch[i] = new MapSqlParameterSource(valueMaps[i]);
batch[i] = new BeanPropertySqlParameterSource(bean);
} }
return batch; return batch;
} }
/** /**
* Create a wrapped value if parameter has type information, plain object if not. * Create a wrapped value if parameter has type information, plain object if not.
* @param source the source of paramer values and type information * @param source the source of parameter values and type information
* @param parameterName the name of the parameter * @param parameterName the name of the parameter
* @return the value object * @return the value object
*/ */
@ -85,13 +112,13 @@ public class SqlParameterSourceUtils {
/** /**
* Create a Map of case insensitive parameter names together with the original name. * Create a Map of case insensitive parameter names together with the original name.
* @param parameterSource the source of paramer names * @param parameterSource the source of parameter names
* @return the Map that can be used for case insensitive matching of parameter names * @return the Map that can be used for case insensitive matching of parameter names
*/ */
public static Map<String, String> extractCaseInsensitiveParameterNames(SqlParameterSource parameterSource) { public static Map<String, String> extractCaseInsensitiveParameterNames(SqlParameterSource parameterSource) {
Map<String, String> caseInsensitiveParameterNames = new HashMap<>(); Map<String, String> caseInsensitiveParameterNames = new HashMap<>();
if (parameterSource instanceof BeanPropertySqlParameterSource) { if (parameterSource instanceof BeanPropertySqlParameterSource) {
String[] propertyNames = ((BeanPropertySqlParameterSource)parameterSource).getReadablePropertyNames(); String[] propertyNames = ((BeanPropertySqlParameterSource) parameterSource).getReadablePropertyNames();
for (String name : propertyNames) { for (String name : propertyNames) {
caseInsensitiveParameterNames.put(name.toLowerCase(), name); caseInsensitiveParameterNames.put(name.toLowerCase(), name);
} }