Как сделать несколько вложений в базе данных с помощью пакета spring JDBC Template?
Мне нужно вставить тысячи записей в базу данных за один раз. Я использую шаблон spring JDBC в своем приложении.
Ниже приведен код, который я написал до сих пор, который выполняет все вставки за один раз. Итак, если у меня 10 000 пользователей, они будут вставлены за один раз. Но я хочу выполнить их в партиях, например, 500 записей в одной партии и так далее.
@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();
}
});
}
Как изменить приведенный выше код так, чтобы вместо employeeList.size() в качестве размера партии мы могли иметь размер партии, например, 500, выполнить их, а затем следующие 500 и так далее?
Пожалуйста, помогите.
Ответы
Ответ 1
Я не уверен, что вы можете сделать это, используя только шаблон JDBC. Возможно, вы могли бы вызывать метод batchUpdate
пошагово, разбивая большой список на куски размером до размера.
Посмотрите здесь:
@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();
}
});
}
}
Ответ 2
Я знаю это немного позже, но вы можете сделать что-то похожее на то, что делает adarshr, за исключением использования Google Guava Lists.partition
, чтобы получить подсписки.
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();
}
});
}
}
Ответ 3
Spring provide Batch operations with multiple batches
here 100 is batch size.
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
}
Ответ 4
Еще упрощенным способом является модификация метода getBatchsize(), как показано ниже.
Нет необходимости в разбиении или подмножестве списка:),
@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;
}
});
}