2 Stimmen

HQL mehrere Updates. Gibt es einen besseren Weg?

Ich habe eine Karte, die ich persistieren möchte. Das Domänenobjekt sieht ungefähr so aus:

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) { ... }
}

Der Standardansatz besteht darin, für jedes Paar ein Setting zu generieren und es mit saveOrUpdate() zu speichern. Aber das führt zu viel zu vielen Abfragen, da ich viele Einstellungen gleichzeitig speichern muss, und es beeinträchtigt die Leistung erheblich. Gibt es eine Möglichkeit, dies mit einer einzigen Update-Abfrage zu tun?

UPD: Okay, vielleicht gibt es eine hql-Syntax zum Aktualisieren von mehreren Zeilen? Etwas wie

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

1voto

Kannan Ekanath Punkte 15569

Wenn jede Einstellung eine Zeile in einer Tabelle ist, müssen entsprechend viele Update-Anweisungen ausgestellt werden. Ein paar Dinge, auf die man achten sollte, wären

1) Anpassen der Hibernate-Batch-Größe auf etwa 20, was bedeutet, dass, obwohl Hibernate 20 Updates durchführt, sie alle als Batch gesendet werden (mit hoffentlich einem Netzwerk-Roundtrip, da Treiber das Batching ermöglichen)

2) Anpassen Ihres Dao-Codes/Transaktionslogik, um Dinge in Batches zu erledigen

3) Verwendung eines gespeicherten Verfahrens und Übergeben von Array-Werten (Hibernate und gespeicherte Prozeduren sind meiner Meinung nach keine guten Freunde)

0voto

Thierry Punkte 5010

Ich kenne keine Syntax, die es ermöglichen würde, mehrere WHERE-Anweisungen wie die von Ihnen geschriebene zu haben.

Vergewissern Sie sich, dass Sie das Batching verwenden. Wenn nicht, versuchen Sie Ihre Updates damit aktiviert.

Wenn der Wert, den Sie zum Aktualisieren der Einstellungstabelle verwenden möchten, bereits irgendwo anders in der Datenbank vorhanden ist, sollte es möglich sein, ein einziges Update durchzuführen. Das könnte schneller sein.

Wenn die Daten noch nicht in der Datenbank sind, können Sie sie in einer temporären Tabelle einfügen, bevor Sie eine einzelne Update-Abfrage ausführen, aber hier benötigen Sie SQL-Abfragen (was mit Hibernate möglich ist).

Aber dieser einzelne Update-Befehl könnte immer noch zu langsam sein. Die letzte Lösung (ohne die Logik des Anwendungsfalls vollständig neu zu überdenken), die ich kenne, ist eine 'SELECT FOR UPDATE'-Anweisung. Das ist Raw JDBC, aber mit Spring JdbcTemplate ist es nicht so schmerzhaft. Sie wählen alle Zeilen aus, die Sie aktualisieren möchten (wenn die Anfrage schneller ausgeführt wird, könnten Sie mehr auswählen, aber in diesem Fall würden Sie sich auf die Netzwerkressourcen auswirken, indem Sie mehr Zeilen aus der Datenbank erhalten als nötig), und aktualisieren sie dann mithilfe von JDBC, während Sie sie abrufen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X