#java #sql #postgresql #jooq
Вопрос:
Мне нужно «вставить» список предметов.
class Item {
private UUID id;
private UUID anotherId;
private List<String> things;
...
}
Если элемент id
и anotherId
уже существует, другие значения должны быть заменены новым элементом. Если это не так, элемент должен быть вставлен как новая запись.
Я наткнулся на batchMerge
JOOQ и подумал, что это похоже на «upsert». К сожалению, в Интернете мало документации, так как это довольно новый метод JOOQ на момент написания.
Я пытался
List<ItemRecord> items = ... //built from context.newRecord(ITEM) then added to a list
context.batchMerge(items).execute();
думая, что он автоматически получит обновленные поля. Значения не обновляются, если строка уже существует. Он вставляет новую запись, если она еще не существует.
Я наткнулся на эту документацию merge
, но не знаю, как ее перевести batchMerge
. https://www.jooq.org/doc/3.1/manual/sql-building/sql-statements/merge-statement/
Я довольно новичок в SQL и JOOQ. Я использую PostgreSQL в качестве базы данных.
Комментарии:
1. Я вижу тег <sql>, но действительно ли это связано с языком SQL <sql>?
2. Вы найдете все, что хотите знать, в документе API: jooq.org/javadoc/latest/org.jooq/org/jooq/…
3. Вставить… По дубликату ключа может помочь?
Ответ №1:
В настоящее время (по состоянию на 3.15 jOOQ) пакетные выполнения в jOOQ не могут извлекать сгенерированные идентификаторы, см.: https://github.com/jOOQ/jOOQ/issues/3327
Однако, поскольку вы используете UUID
типы для своих идентификаторов (в отличие от сгенерированных последовательностями), вам вообще нужен сервер для генерации идентификаторов? С таким же успехом вы можете сгенерировать их уже в клиенте и вставить вместе с остальными.
Ответ №2:
JOOQ batchMerge()
работает, как и ожидалось, с Postgres.
На самом деле проблема была не в ДЖУКЕ. Служба, которая вызывает метод репо для batchMerge, помечена @Transactional
. Это весенняя аннотация, которая имеет функцию отката. Вот почему кажется, что он не сохраняется в базе данных. Я отметил это как @Transactional(noRollbackFor = CustomException.class)
решение моей проблемы.