New to Spring, I am trying to insert a List
into a table. Until now I have been using the SqlParameterSource
for b
You can not directly use your bean in NamedParameterJdbcTemplate's batchUpdate, NamedParameterJdbcTemplate's batchUpdate accepts params in form of array only. Either an array of SqlParameterSource or an array of Map.
Here I will demonstrate how you can use array of Map to achieve your goal.
Considering the above problem, convert your List of Bean into array of map, Each map corresponds to one row to be inserted or One Bean object, field and its value are stored as key-value pair inside the map where key is the field name and value is the value of the field under consideration.
@Autowired
private NamedParameterJDBCTemplate v2_template;
public int[] bulkInsertIntoSiteTable(List<SiteBean> list){
String yourQuery = "insert into sitestatus (website, status, createdby)
values (:website, :status, :username)"
Map<String,Object>[] batchOfInputs = new HashMap[list.size()];
int count = 0;
for(SiteBean sb : list.size()){
Map<String,Object> map = new HashMap();
map.put("website",sb.getWebsite());
map.put("status",sb.getStatus());
map.put("username",sb.getUsername());
batchOfInputs[count++]= map;
}
int[] updateCounts = v2_template.batchUpdate(yourQuery,batchOfInputs);
return updateCounts;
}
I tested with code.
Map<String, Object>[] rs = new Map<String, Object>[1];
Map<String, Object> item1 = new HashMap<>();
item1.put("name", "Tien Nguyen");
item1.put("age", 35);
rs[0] = item1;
NamedParameterJdbcTemplate jdbc = new NamedParameterJdbcTemplate(datasource);
// datasource from JDBC.
jdbc.batchUpdate("call sp(:name, :age)", rs);
Hope it is easy to know. Thanks
As per Spring NamedParameterJDBCTemplate
docs, found here, this method can be used for batch updating with maps.
int[] batchUpdate(String sql, Map<String,?>[] batchValues)
The real challange was to a get an array of Map<String, Object>
from a corresponding List<Map<String, Object>>
. I used the following code to get the array and perform the batch update.
public static Map<String, Object>[] getArrayData(List<Map<String, Object>> list){
@SuppressWarnings("unchecked")
Map<String, Object>[] maps = new HashMap[list.size()];
Iterator<Map<String, Object>> iterator = list.iterator();
int i = 0;
while (iterator.hasNext()) {
Map<java.lang.String, java.lang.Object> map = (Map<java.lang.String, java.lang.Object>) iterator
.next();
maps[i++] = map;
}
return maps;
}
There is another way to awoid @SuppressWarnings("unchecked")
.
public static final String INSERT_INTO = "INSERT INTO {0} ({1}) VALUES ({2})";
private NamedParameterJdbcTemplate template;
template.batchUpdate(insertQuery(rowMaps.get(0)), batchArgs(mapRows));
/**
* Create SQL instruction INSERT from Map record
*
* @return literal INSERT INTO [schema].[prefix][table_name] (column1, column2, column3, ...)
* VALUES (value1, value2, value3, ...);
*/
public String insertQuery(Map<String, String> rowMap) {
String schemaTable = Objects.isNull(getSchema()) ? table : getSchema() + "." + table;
String splittedColumns = String.join(",", rowMap.keySet());
String splittedValues = rowMap.keySet().stream()
.map(s -> ":" + s).collect(Collectors.joining(","));
return MessageFormat.format(INSERT_INTO, schemaTable, splittedColumns, splittedValues);
}
private MapSqlParameterSource[] batchArgs(List<Map<String, String>> mapRows) {
int size = mapRows.size();
MapSqlParameterSource[] batchArgs = new MapSqlParameterSource[size];
IntStream.range(0, size).forEach(i -> {
MapSqlParameterSource args = new MapSqlParameterSource(mapRows.get(i));
batchArgs[i] = args;
});
return batchArgs;
}
Best regards