HQL несколько обновлений. Есть ли способ лучше? - PullRequest
2 голосов
/ 16 марта 2010

У меня есть карта, которую я хочу сохранить. Доменный объект выглядит примерно так:

public class Settings {
    private String key;
    private String value;

    public String getKey() { ... }
    public String getValue() { ... }
    public void setKey(String key) { ... }
    public void setValue(String value) { ... }
}

Стандартный подход заключается в генерации Setting для каждой пары и saveOrUpdate() ее. Но он генерирует слишком много запросов, потому что мне нужно сохранять множество настроек за раз, и это действительно влияет на производительность. Есть ли способ сделать это с помощью одного запроса на обновление?

UPD: Хорошо, возможно, существует синтаксис hql для обновления нескольких строк? Что-то вроде

update Settings s1 set s1.value = :value1 where s1.key = :key1
                s2 set s2.value = :value2 where s2.key = :key2

Ответы [ 2 ]

1 голос
/ 16 марта 2010

Если каждый параметр представляет собой строку в таблице, то должно быть выполнено столько операторов обновления. Но несколько вещей, на которые стоит посмотреть, будут

1) Изменение размера пакета в режиме гибернации, скажем, около 20, что означает, что, хотя в режиме гибернации выдается 20 обновлений, все они отправляются в пакетном режиме (с надеждой, что одна сетевая передача в оба конца обеспечивает драйверы для пакетирования)

2) Изменение вашего даос-кода / логики транзакций для пакетной обработки

3) Наличие хранимой процедуры и передача значений массива (я думаю, что hibernate и Storeprocs не очень хорошие друзья)

0 голосов
/ 16 марта 2010

Я не знаю ни одного синтаксиса, который позволял бы иметь несколько выражений where, подобных написанному вами.

Убедитесь, что вы используете дозирование. Если нет, попробуйте обновить его с активированным.

Если значение, которое вы хотите использовать для обновления таблицы настроек, уже есть в базе данных где-то еще, вы сможете выполнить одно обновление. Это может быть быстрее.

Если данных еще нет в базе данных, вы можете вставить их во временную таблицу перед выполнением одного запроса на обновление, но здесь вам потребуются sql-запросы (что возможно в hibernate).

Но этот единственный оператор обновления все еще может быть слишком медленным. последнее решение (без переосмысления логики варианта использования), которое я знаю, - это утверждение «выбрать для обновления». Это сырой jdbc, но с пружинным JdbcTemplate это не так больно. Вы выбираете все строки, которые хотите обновить (если это сделает запрос быстрее, вы можете выбрать больше, но в этом случае вы окажете влияние на сетевой ресурс, получив больше строк из базы данных, чем необходимо), а затем обновите они используют jdbc, когда вы их извлекаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...