Dieser Artikel beschreibt die Methode des Hibernate -Batch -Betriebs. Teilen Sie es für Ihre Referenz wie folgt weiter:
Hibernate -Batch -Verarbeitung
Hibernate betreibt die Datenbank auf objektorientierte Weise vollständig. Wenn ein anhaltendes Objekt im Programm auf objektorientierte Weise betrieben wird, wird es automatisch in einen Vorgang in der Datenbank umgewandelt. Wenn beispielsweise die Delete () -Methode von Session zum Löschen eines persistenten Objekts aufgerufen wird, ist Hibernate für das Löschen der entsprechenden Datensätze verantwortlich. Bei der Ausführung der festgelegten Methode des persistenten Objekts konvertiert Hibernate automatisch in die entsprechende Aktualisierungsmethode und ändert die entsprechenden Datensätze der Datenbank.
Die Frage ist, ob 100.000 Datensätze gleichzeitig aktualisiert werden müssen, müssen Sie 100.000 Datensätze nacheinander laden und dann die festgelegte Methode aufrufen - dies ist nicht nur umständlich, sondern auch die Leistung des Datenzugriffs ist sehr schlecht. Für dieses Stapelverarbeitungsszenario bietet Hibernate eine Stapelverarbeitungslösung. Im Folgenden wird aus drei Aspekten vorgegangen, wie man sich dieser Stapelverarbeitungssituation gegenübersieht: Stapelinsertion, Batch -Update und Stapeldeletion.
1 Batcheinsatz
Wenn Sie 100.000 Datensätze in die Datenbank einfügen müssen, kann Hibernate normalerweise Folgendes verwenden:
Sitzung Session Session.save (kunde);} tx.commit (); session.close ();
Aber wenn dieses Programm ausgeführt wird, wird es immer irgendwann scheitern und eine Ausnahme wird ausgeworfen. Dies liegt daran, dass die Sitzung von Hibernate einen erforderlichen Cache der Stufe 1 enthält und alle Benutzerinstanzen im Cache-Bereich auf Sitzungsebene zwischengespeichert werden.
Um dieses Problem zu lösen, gibt es eine sehr einfache Idee: Aktualisieren Sie die von der Sitzung zwischengespeicherten Daten regelmäßig in die Datenbank, anstatt sie immer auf Sitzungsebene zu zwischenspeichern. Sie können in Betracht ziehen, einen Akkumulator zu entwerfen, der für jede gespeicherte Benutzerinstanz um 1 erhöht wird. Bestimmen Sie, ob die Daten im Sitzungs -Cache basierend auf dem Akkumulatorwert in die Datenbank gespült werden müssen.
Hier ist ein Codeausschnitt, der 100.000 Benutzerinstanzen hinzufügt:
private void testuser () löst Ausnahme aus {// Sitzungssitzung öffnen Session = hibernateUtil.currentSession (); // Transaktionstransaktion starten tx = session.beginTransaction (); // 100 000 Mal Schleifen und 100 000 Datensätze für (int i = 0; i <1000000; i ++) {// Benutzerinstanz -Benutzer u1 = new user (); u1.setName ("xxxxx" + i); U1.Setage (i); U1.SetNationality ("China"); // die Benutzerinstanz -Sitzung.Save (U1) abschneidet; // Wenn der Akkumulator ein Vielfaches von 20 ist, spülen Sie die Daten in der Sitzung in die Datenbank und löschen Sie den Sitzungscache, wenn (i % 20 == 0) {session.flush (); Session.clear (); tx.commit (); tx = session.beginTransaction (); }} // Transaktion tx.commit (); // Transaktion HibernateUtil.Closession ();};}Wenn im obigen Code i%20 == 0, werden die zwischengespeicherten Daten an der Sitzung manuell in die Datenbank geschrieben und die Transaktion manuell eingereicht. Wenn die Transaktion nicht eingereicht wird, werden die Daten weiterhin im Transaktionsbüro zwischengespeichert - sie wurde nicht in die Datenbank eingegeben, was auch eine Ausnahme des Speicherüberlaufs verursacht.
Dies ist die Verarbeitung von Cache auf Sitzungsebene, und der sekundäre Cache des SessionFactory sollte ebenfalls durch die folgende Konfiguration ausgeschaltet werden.
hibernate.cache.use_second_level_cache false
Hinweis: Zusätzlich zur manuellen Löschen des Cache auf Sitzungsebene ist es am besten, den Sekundär-Cache auf SessionFactory-Ebene auszuschalten. Andernfalls kann auch wenn der Cache auf Sitzungsebene manuell gelöscht wird, eine Ausnahme ausgelöst werden, da auf der SessionFactory-Ebene immer noch ein Cache vorhanden ist.
2 Batch -Updates
Die oben beschriebene Methode eignet sich auch für Batch -Update -Daten. Wenn Sie mehrere Datenzeilen zurückgeben müssen, können Sie die SCROLL () -Methode verwenden, um die Leistungsvorteile, die von serverseitigen Cursoren mitgelegt wurden, voll zu nutzen. Hier ist ein Code -Snippet für Batch -Updates:
private void testuser () löst Ausnahme aus {// Sitzungssitzung öffnen Session = hibernateUtil.currentSession (); // starten Sie die Transaktionstransaktion tx = session.BeginTransaction (); // Alle Datensätze in der Benutzertabelle scrollableresults user = session.createquery ("From User") .SetCachemode (Cachemode.ignore) .Scroll (scrollMode.forward_only) abfragen. int count = 0; // Transaktion alle Datensätze in der Benutzertabelle wob u.setName ("neuer Benutzername" + count); // Wenn die Anzahl ein Vielfaches von 20 ist, spülen Sie das aktualisierte Ergebnis aus der Sitzung zur Datenbank if (++ count % 20 == 0) {session.flush (); Session.clear (); }} tx.commit (); HibernateUtil.closesSession ();} Obwohl Batch -Updates durchgeführt werden können, ist der Effekt sehr schlecht. Die Ausführungseffizienz ist nicht hoch, und es werden zuerst Datenabfrage erforderlich, und dann wird die Datenaktualisierung durchgeführt. Dieses Update wird ein Zeilen-für-Linie-Update sein, dh jedes Mal, wenn eine Reihe von Datensätzen aktualisiert wird, muss eine Update-Anweisung ausgeführt werden und die Leistung ist sehr niedrig.
Um dies zu vermeiden, bietet Hibernate eine HQL -Syntax, die SQL für Stapel -Updates und Stapeldeletion ähnelt.
3 SQL-Batch-Batch-Update/Löschung
Die von Hibernate bereitgestellten HQL -Anweisungen unterstützen auch die Batch -Update und das Löschen der Syntax.
Das Syntaxformat von Batch -Update und Löschen von Anweisungen lautet wie folgt:
Update | Löschen aus? Klassenname [wo wo_conditions]
Über das obige Syntaxformat sind vier Punkte erwähnenswert:
● In der From -Klausel ist das aus dem Schlüsselwort aus dem Schlüsselwort optional. Das heißt, Sie können überhaupt nicht aus Schlüsselwörtern schreiben.
● In der From -Klausel kann nur einen Klassennamen vorhanden sein, und der Klassenname kann keinen Alias haben.
● Sie können weder explizit noch implizite Verbindungen in Batch -HQL -Anweisungen verwenden. Unterabfragen können jedoch in der Where -Klausel verwendet werden.
● Die gesamte Where -Klausel ist optional.
Unter der Annahme, dass Sie das Namensattribut der Benutzerklasseninstanz ändern müssen, können Sie den folgenden Code -Snippet verwenden:
private void testuser () löst Ausnahme aus {// Sitzungssitzung öffnen Session = hibernateUtil.currentSession (); // Transaktionstransaktion starten tx = session.beginTransaction (); // Batch Update HQL Anweisung String String hqlupdate = "Benutzer set name =: newname"; // Update int updateEntities = session.createquery (hqlupdate) .setString ("newname", "neuer Name") .ExecuteUpdate (); // Transaktion tx.commit () begehen; HibernateUtil.closesSession ();}Wie aus dem obigen Code ersichtlich ist, ist diese Syntax der ExecuteUpdate -Syntax der vorbereiteten Statement sehr ähnlich. Tatsächlich liehen dieses Batch -Update von HQL direkt von der Aktualisierungsrechnung der SQL -Syntax aus.
Hinweis: Wenn Sie diese Stapel -Update -Syntax verwenden, müssen Sie normalerweise nur die SQL -Update -Anweisung einmal ausführen, um alle Aktualisierungen abzuschließen, mit denen die bedingten Datensätze entsprechen. Es kann jedoch auch erforderlich sein, mehrere Aktualisierungsanweisungen auszuführen, da es spezielle Fälle gibt, wie z. B. Erbschaftskartierung, z. Wenn Batch -Instanzen von Personeninstanzen aktualisiert werden, muss auch die Kundeninstanz aktualisiert werden. Wenn Sie die Kartierungsstrategie für die Subklassen oder die Abbildung der Gewerkschaftsunterklasse verwenden, werden Personen- und Kundeninstanzen in verschiedenen Tabellen gespeichert, sodass mehrere Aktualisierungsanweisungen erforderlich sind.
Führen Sie ein HQL -Löschen aus und verwenden Sie die Methode query.executeUpdate (). Das Folgende ist ein Code -Snippet, das alle oben genannten Datensätze gleichzeitig löscht:
private void testuser () löst Ausnahme aus {// Session Instance Session Session = hibernateUtil.currentSession (); // Transaktionstransaktion starten tx = session.beginTransaction (); // Batch -Löschungs -HQL -Anweisung String String hqlupdate = "Benutzer löschen"; // Batch -Löschung int updateEntities = session.createquery (HQLUPDATE) .ExecuteUpDate (); // Transaktion tx.commit () begehen; // Session HibernateUtil.ClosesSession ();} schließen;}Gibt einen Ganzzahlwert nach der Methode query.executeUpdate () zurück, bei der die Anzahl der von dieser Operation betroffenen Datensätze betroffen ist. Tatsächlich werden die zugrunde liegenden Operationen von Hibernate über JDBC durchgeführt. Wenn daher Stapel von Aktualisierungs- oder Löschvorgängen vorhanden ist, die in mehrere Aktualisierungs- oder Löschanweisungen konvertiert werden, gibt die Methode die Anzahl der von der letzten SQL -Anweisung betroffenen Datensätze zurück.
Ich hoffe, dass die Beschreibung in diesem Artikel für Java -Programme aller hilfreich ist, die auf dem Hibernate -Framework basieren.