Der Cache der Sitzung wird mit miteinander verbundenen Objektdiagrammen gespeichert. Wenn Hibernate Kundenobjekte aus der Datenbank lädt, werden standardmäßig alle zugeordneten Auftragsobjekte gleichzeitig geladen. Nehmen Sie Kunden- und Bestellkurse als Beispiele an, dass der Foreign -Schlüssel der Customer_ID der Tabelle der Bestellungen null sein darf
Die folgende Session的find() wird verwendet, um alle Kundenobjekte in der Datenbank abzurufen:
List customerLists=session.find("from Customer as c");
Bei der obigen Ausführung der oben ausführenden Methode find() wird Hibernate zuerst alle Datensätze in der Kundentabelle abfragt und dann die Tabelle der Bestellungen mit Referenzbeziehungen basierend auf der ID jedes Datensatzes abfragt. Hibernate führt die folgenden ausgewählten Aussagen wiederum aus:
Wählen Sie * von Kunden aus;
Wählen Sie * aus Bestellungen, wobei Customer_id = 1;
Wählen Sie * aus Bestellungen, wobei Customer_id = 2;
Wählen Sie * aus Bestellungen, wobei Customer_id = 3;
Wählen Sie * aus Bestellungen, wobei Customer_id = 4;
In den oben genannten 5 lädt Hibernate schließlich 4 Kundenobjekte und 5 Bestellobjekte, wodurch ein zugeordnetes Objektdiagramm im Speicher erstellt wird.
Hibernate verwendet die Standard -Such -Now -Richtlinie, wenn Sie mit dem Kunden zugeordnete Auftragsobjekte abrufen. In dieser Suchstrategie gibt es zwei Hauptmängel:
(1) Die Anzahl der ausgewählten Aussagen ist zu groß und der häufige Zugriff auf die Datenbank beeinflusst die Abrufleistung. Wenn Sie Kundenobjekte abfragen müssen, muss N+1 Abfrageanweisung ausgestellt werden. Dies ist das klassische N+1 -Abfrageproblem. Diese Suchstrategie verwendet keine SQL -Verbindungsabfragefunktion. Beispielsweise können die obigen 5 -Auswahlanweisungen durch die folgende 1 -Auswahlanweisung vollständig ausgeführt werden:
Wählen Sie * von Kunden hinterlassenen Außenbefehle aus
auf customer.id = ordns.customer_id
Die obige SELECT -Anweisung verwendet die linke äußere Join -Abfragefunktion von SQL, mit der alle Datensätze der Kundentabelle und die Datensätze der Tabelle übereinstimmende Bestellungen in einer ausgewählten Anweisung abfragen können.
(2) In Situationen, in denen die Anwendungslogik nur auf Kundenobjekte zugreifen muss, jedoch keine Bestellobjekte, ist das Laden von Auftragsobjekten völlig unnötig. Diese unnötigen Ordnung Objekte verschwenden viel Speicherplatz.
Um die oben genannten Probleme zu lösen, bietet Hibernate zwei weitere Suchstrategien an: eine verzögerte Suchstrategie und eine dringende Strategie für die Suchstrategie für die Verknüpfung aus der Verknüpfung. Die verzögerte Abrufstrategie kann eine redundante Belastung der zugehörigen Objekte vermeiden, auf die die Anwendung nicht zugreifen muss. Die dringende Strategie für die Abruf von linken äußeren Verbindungen nutzt die Abfragefunktion von SQL vollständig und kann die Anzahl der ausgewählten Aussagen reduzieren.
Leistungsprobleme müssen beim Zugriff auf Datenbanken berücksichtigt werden. Nach der Einstellung der 1-zu-Viele-Beziehung tritt das legendäre N +1-Problem in der Abfrage auf.
1) 1 bis viele, in 1 Quadrat, N -Objekten können gefunden werden, dann muss der mit N -Objekten zugeordnete Satz herausgenommen werden, sodass die ursprüngliche SQL -Abfrage n +1 wird
2) Viele bis 1. Wenn Sie M-Objekte in mehreren Parteien abfragen, wird das 1-Party-Objekt, das M-Objekten entspricht, herausgenommen und wird auch zu M+1.
1) Lazy = true, Hibernate3 hat bereits standardmäßig auf Lazy = true gegangen; Wenn faul = true, wird das zugehörige Objekt nicht sofort abgefragt. Die Abfrageaktion tritt nur dann auf, wenn das zugeordnete Objekt (Zugriff auf seine Attribute, Nicht-ID-Felder).
2) Stufe 2 Cache. Wenn das Objekt viel weniger aktualisiert, gelöscht und hinzugefügt ist als Abfragen, hat die Anwendung des Cache Level 2 keine Angst vor n +1 Problemen, denn selbst wenn die erste Abfrage langsam ist, ist der Cache -Treffer danach sehr schnell.
Verschiedene Lösungen und unterschiedliche Ideen, aber der zweite verwendet einfach wieder n +1.
3) Natürlich können Sie auch fetch=join(annotation : @ManyToOne() @Fetch(FetchMode.JOIN)) festlegen.
Das Obige dreht sich alles um die kurze Diskussion dieses Artikels über die Hibernate N+1 -Ausgabe, und ich hoffe, dass es für alle hilfreich sein wird. Interessierte Freunde können weiterhin auf andere verwandte Themen auf dieser Website verweisen. Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!