2008-11-16 7 views
6

Ich habe eine große Anzahl von Zeilen in der Datenbank, aus denen ich ein XML-Dokument erstellen muss. Ich benutze Hibernate 3. Die grundlegende list() -Methode in Criteria und Query-Schnittstellen sieht gefährlich aus: Ich quess es ziemlich viel muss alle Datensätze in den Speicher gelesen werden, auch wenn ich nur über sie iterieren. Oder gibt es etwas faule Ladezauber? Wenn nicht, habe ich scheinbar noch zwei Optionen: mit scroll() oder iterate() von Query (scroll ist auch in Criteria vorhanden). iterate sieht auch nicht sehr gut aus, wenn ich minimale SQL-Roundtrips haben möchte: "Die erste SQL-Abfrage gibt nur Identifikatoren zurück". Also habe ich recht, muss ich dafür scroll() benutzen?Hibernate: Vermeiden Sie das Lesen aller Datensätze in den Speicher

+0

Dieses Zeug auch auf NHibernate angewendet :) –

Antwort

1

Verwenden Sie die setMaxResults() - Methode für Kriterien.

Criteria crit = sess.createCriteria(Cat.class); 
crit.setMaxResults(maxResults); 
crit.setFirstResult(firstResultIndex); 
List cats = crit.list(); 

http://hibernate.org/hib_docs/v3/reference/en/html/querycriteria.html

http://www.hibernate.org/hib_docs/v3/api/org/hibernate/Criteria.html

+0

Was ich tun möchte, ist alle Ergebnisse in transaktionaler Weise zu haben. Ich nehme an, du meinst, ich sollte das ganze große Ergebnis aus Teilen zusammensetzen. Kann ich diese verwenden, um meine konsistente, große Ergebnismenge zusammenzufassen, so dass ich ab einem bestimmten Zeitpunkt wirklich eine Momentaufnahme erhalte. – auramo

+0

Ich bin mir nicht sicher, was Sie mit "haben alle Ergebnisse in einer transaktionalen Mode" bedeuten. –

+0

Was ich meine ist, dass meine Ergebnismenge eine Momentaufnahme ist, keine Schreib-/Löschvorgänge, die zwischen anderen Clients auftreten, beeinflussen dies. – auramo

-1

Auch einen Blick auf Batch-Abschnitt 19.1.4 und 19.1.5 Abrufen tun sollten.

Insert into BatchTable (ID, Seq) Select (O.ID, Sequence.Next) 
From MyObject O Where ... 

In kleinen Einheiten der Arbeitsbelastung in den Objekten: http://www.hibernate.org/hib_docs/v3/reference/en-US/html_single/#queryhql-joins-forms

+0

Wissen Sie, ob diese Stapelabfragen (zB 10, 10 und 5 Katzen im Beispiel) alle in der Liste enden (wenn ich die Tabelle mit list() im Speicher abfrage, während ich sie durchlaufe? Oder kann Hibernate die erste Charge, wenn ich mit der nächsten Charge fortfahre (z. B. die nächsten 10 Katzen nach den ersten 10 Katzen). – auramo

0

Dies ist, was auf plane ich tun: eine temporäre Tabelle erstellen mit dem Objekt-IDs aller Zeilen muß ich exportieren :

Select Min(B.Seq), Max(B.Seq) From BatchTable; 

for (batch = minBatch; batch <= maxBatch; batch += size) { 
beginTransaction(); 
results = query("Select O From MyObject O, BatchTable B 
        Where O.ID = B.ID and (? <= B.Seq AND B.Seq < ?)"); 

exportXML(results); 
for (MyObject O : results) { 
    O.setProcessed(True); 
    O.update(); 
} 
commit(); 
} 
1

Wenn Sie als procesed die Objekte nicht ab markieren müssen, können Sie einfach die Objekte aus der Sitzung verwenden scroll() und vertreiben, wie Sie mit ihnen fertig sind.

2

Versuchen unter Verwendung scroll() in Verbindung mit diesem:

http://docs.jboss.org/hibernate/core/3.3/api/org/hibernate/StatelessSession.html

Ein Befehlsorientierte API für Bulk-Operationen mit einer Datenbank durchgeführt wird. Eine statusfreie Sitzung implementiert weder einen Cache der ersten Ebene, noch interagiert sie mit einem Cache der zweiten Ebene, noch implementiert sie transaktionale Write-Behind- oder automatische Dirty-Überprüfung, noch kaskadieren Operationen mit zugeordneten Instanzen. Sammlungen werden von einer zustandslosen Sitzung ignoriert. Operationen, die über eine zustandslose Sitzung ausgeführt werden, umgehen das Ereignismodell und die Interzeptoren von Hibernate. Stateless-Sitzungen sind anfällig für Daten-Aliasing-Effekte, da ein Cache der ersten Ebene fehlt.

Bei bestimmten Arten von Transaktionen kann eine zustandslose Sitzung etwas schneller ablaufen als eine zustandsbehaftete Sitzung.

Verwandte Themen