Учитывая postgresql таблицу
Table "public.test"
Column | Type | Modifiers
----------+-----------------------------+-----------
id | integer | not null
info | text |
И следующие значения:
# select * from test;
id | info
----+--------------
3 | value3
4 | value4
5 | value5
Как вы, возможно, знаете, с postgresql вы можете использовать такие операторы для обновления кратных строк с разными значениями :
update test set info=tmp.info from (values (3,'newvalue3'),(4,'newvalue4'),(5,'newvalue5')) as tmp (id,info) where test.id=tmp.id;
И это приводит к тому, что таблица обновляется в отдельных запросах до:
# select * from test;
id | info
----+--------------
3 | newvalue3
4 | newvalue4
5 | newvalue5
Я искал повсюду, как как заставить спящий режим генерировать такие операторы для запросов на обновление. Я знаю, как заставить его работать для запросов на вставку (с параметром reWriteBatchedInserts jdb c и параметрами конфигурации пакетной конфигурации гибернации).
Но возможно ли это для запросов на обновление или мне нужно самому писать собственный запрос? Независимо от того, что я делаю, спящий режим всегда отправляет отдельные запросы на обновление в базу данных (я ищу postgresql журналы операторов сервера для этого подтверждения).
2020-06-18 08:19:48.895 UTC [1642] LOG: execute S_6: BEGIN
2020-06-18 08:19:48.895 UTC [1642] LOG: execute S_8: update test set info = $1 where id = $2
2020-06-18 08:19:48.895 UTC [1642] DETAIL: parameters: $1 = 'newvalue3', $2 = '3'
2020-06-18 08:19:48.896 UTC [1642] LOG: execute S_8: update test set info = $1 where id = $2
2020-06-18 08:19:48.896 UTC [1642] DETAIL: parameters: $1 = 'newvalue4', $2 = '4'
2020-06-18 08:19:48.896 UTC [1642] LOG: execute S_8: update test set info = $1 where id = $2
2020-06-18 08:19:48.896 UTC [1642] DETAIL: parameters: $1 = 'newvalue4', $2 = '5'
2020-06-18 08:19:48.896 UTC [1642] LOG: execute S_1: COMMIT
Я всегда нахожу, что это во много раз быстрее выдает один массовый запрос на обновление, чем несколько отдельных обновлений, нацеленных на отдельные строки. Со многими отдельными запросами на обновление, даже если они отправляются в пакете драйвером jdb c, они все равно должны обрабатываться последовательно сервером, поэтому это не так эффективно, как один запрос на обновление, ориентированный на несколько строк. Так что, если у кого-то есть решение, которое не требует написания собственных запросов для моих сущностей, я был бы очень рад!
Обновить
Для дальнейшего уточнения моих вопрос хочу добавить уточнение. Я ищу решение, которое не отказывалось бы от функции грязной проверки Hibernate для обновлений сущностей. Я пытаюсь избежать написания запросов на пакетное обновление вручную в общем случае, когда необходимо обновить несколько базовых c полей с разными значениями в списке сущностей. В настоящее время я изучаю SPI гибернации, чтобы увидеть, выполнимо ли это. org.hibernate.engine.jdbc.batch.spi.Batch
кажется подходящим местом, но я еще не совсем уверен, потому что я никогда ничего не делал с SPI спящего режима). Приветствуются любые идеи!