spring jdbc - example - ¿Cómo hacer inserciones múltiples en la base de datos utilizando el lote de plantillas JDBC de primavera?
jdbctemplate spring boot (4)
La forma aún más simplificada es la modificación del método getBatchsize () como se muestra a continuación que funciona
No hay necesidad de partición o subconjunto de la lista :),
@Override
public void saveBatch(final List<Employee> employeeList) {
final int batchSize = 500;
getJdbcTemplate().batchUpdate(QUERY_SAVE,
new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i)
throws SQLException {
Employee employee = employeeList.get(i);
ps.setString(1, employee.getFirstname());
ps.setString(2, employee.getLastname());
ps.setString(3, employee.getEmployeeIdOnSourceSystem());
}
@Override
public int getBatchSize() {
if (batchSize > employeeList.size()) {
return employeeList.size();
}
return batchSize;
}
});
}
Necesito insertar miles de registros en la base de datos de una sola vez. Estoy utilizando la plantilla JDBC de primavera en mi aplicación.
A continuación se muestra el código que he escrito hasta ahora, que ejecuta todas las inserciones de una sola vez. Por lo tanto, si tengo 10.000 usuarios, se insertan a la vez. Pero lo que quiero es ejecutarlos en lotes, por ejemplo, 500 registros en un lote y así sucesivamente.
@Override
public void saveBatch(final List<Employee> employeeList) {
final int batchSize = 500;
getJdbcTemplate().batchUpdate(QUERY_SAVE,
new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i)
throws SQLException {
Employee employee = employeeList.get(i);
ps.setString(1, employee.getFirstname());
ps.setString(2, employee.getLastname());
ps.setString(3, employee.getEmployeeIdOnSourceSystem());
}
@Override
public int getBatchSize() {
return employeeList.size();
}
});
}
¿Cómo cambio el código anterior para que en lugar de employeeList.size () como tamaño de lote podamos tener un tamaño de lote como, por ejemplo, 500, ejecutarlos y luego los próximos 500 y así sucesivamente?
Por favor ayuda.
No estoy seguro de poder hacerlo usando solo la plantilla JDBC. Tal vez podría invocar el método batchUpdate
en pasos, batchUpdate
la lista grande en trozos de tamaño de lote.
Echa un vistazo aquí:
@Override
public void saveBatch(final List<Employee> employeeList) {
final int batchSize = 500;
for (int j = 0; j < employeeList.size(); j += batchSize) {
final List<Employee> batchList = employeeList.subList(j, j + batchSize > employeeList.size() ? employeeList.size() : j + batchSize);
getJdbcTemplate().batchUpdate(QUERY_SAVE,
new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i)
throws SQLException {
Employee employee = batchList.get(i);
ps.setString(1, employee.getFirstname());
ps.setString(2, employee.getLastname());
ps.setString(3, employee.getEmployeeIdOnSourceSystem());
}
@Override
public int getBatchSize() {
return batchList.size();
}
});
}
}
Sé que es un poco tarde, pero podrías hacer algo similar a lo que está haciendo @adarshr, excepto usar Google Guava Lists.partition
para obtener las sublistas.
public void saveBatch(final List<Employee> employeeList) {
final int batchSize = 500;
List<List<Employee>> batchLists = Lists.partition(employeeList, batchSize);
for(List<Employee> batch : batchLists) {
getJdbcTemplate().batchUpdate(QUERY_SAVE, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i)
throws SQLException {
Employee employee = batch.get(i);
ps.setString(1, employee.getFirstname());
ps.setString(2, employee.getLastname());
ps.setString(3, employee.getEmployeeIdOnSourceSystem());
}
@Override
public int getBatchSize() {
return batch.size();
}
});
}
}
Spring proporciona operaciones por lotes con varios lotes. En el siguiente ejemplo, el tamaño del lote es 100.
public class JdbcActorDao implements ActorDao {
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public int[][] batchUpdate(final Collection<Actor> actors) {
int[][] updateCounts = jdbcTemplate.batchUpdate(
"update t_actor set first_name = ?, last_name = ? where id = ?",
actors,
100,
new ParameterizedPreparedStatementSetter<Actor>() {
public void setValues(PreparedStatement ps, Actor argument) throws SQLException {
ps.setString(1, argument.getFirstName());
ps.setString(2, argument.getLastName());
ps.setLong(3, argument.getId().longValue());
}
});
return updateCounts;
}
// ... additional methods
}