Как пакетное обновление с помощью jooq - PullRequest
1 голос
/ 13 июля 2020

Использование следующего способа обновления с помощью jOOQ.

for (Balance balance : balances) {
       dslContext.update(BALANCE)
                 .set(BALANCE.AMOUNT, balance.getAmount())
                 .where(BALANCE.ID.eq(balance.getId))
                 .execute();
}

Это перебирает все балансы и вставляет каждый. Я знаю, что это можно сделать с помощью UpdatableRecord. Но я хочу избежать получения баланса из базы данных. Баланс - это таблица с более чем 8 полями, но меня интересует обновление только одного поля. Есть ли другой способ сделать это без UpdatableRecord?

Ответы [ 2 ]

3 голосов
/ 13 июля 2020

Ваш код в порядке, но вы можете использовать пакетные обновления следующим образом:

List<UpdateConditionStep<BalanceRecord> updates = new ArrayList<>();
for (Balance balance : balances) {
   updates.add(dslContext.update(BALANCE)
             .set(BALANCE.AMOUNT, balance.getAmount())
             .where(BALANCE.ID.eq(balance.getId)));
}

dslContext.batch(updates).execute();

Документация: https://www.jooq.org/doc/3.14/manual-single-page/#batch -execution

Просто подсказка: Будьте будьте осторожны с потерянными обновлениями, если вы обновляете баланс без блокировки.

0 голосов
/ 13 июля 2020

Вы по-прежнему можете использовать UpdatableRecord, если хотите удобство DSLContext.batchUpdate(), без предварительного извлечения всех записей из базы данных. Предполагая, что вы используете генератор кода и генерируете записи, у вас будет BalanceRecord:

ctx.batchUpdate(balances
   .stream()
   .map(b -> { 
       var r = new BalanceRecord();
       r.setAmount(b.getAmount());
       r.setId(b.getId());
       r.changed(BALANCE.ID, false); // Prevent setting the ID to itself
       return r;
   })
   .collect(toList()))
   .execute();

Это создаст для вас пакетный оператор за кулисами.

...