Ich verwende Hibernate, um eine Verbindung zu meiner Datenbank herzustellen. Ich habe eine Vererbungsstruktur in meiner Anwendung. Das Problem ist, dass, wenn ich eine Abfrage wie "von Tier" mache, es einen linken äußeren Join für die Klasse Animal, seine Unterklassen und alle Zuordnungen für Animal und seine Unterklassen macht. Wie vermeide ich diese Situation.Ich möchte die Daten nur laden, wenn ich es durch einen Abrufmodus in meiner Kriterienabfrage angeben?
Ja, Hibernate unterstützt polymorphe Abfragen. Aus der Dokumentation:
14.8. Polymorphe Abfragen
Eine Abfrage wie:
%Vor%gibt Instanzen nicht nur von
%Vor%Cat
, sondern zurück auch von Unterklassen wieDomesticCat
. Hibernate-Abfragen können any Java benennen Klasse oder Schnittstelle in der from-Klausel. Die Abfrage gibt alle Instanzen zurück persistente Klassen, die das erweitern Klasse oder implementieren Sie die Schnittstelle. Das Die folgende Abfrage würde alle zurückgeben persistente Objekte:Die Schnittstelle
%Vor%Named
könnte sein implementiert von verschiedenen hartnäckigen Klassen:Diese letzten zwei Abfragen erfordern mehr als ein SQL
SELECT
. Das heisst dass die order by-Klausel dies nicht tut Ordne das gesamte Ergebnis korrekt an. Es bedeutet auch, dass Sie diese nicht anrufen können Abfragen mitQuery.scroll()
.
Dies ist das Standardverhalten (genannt impliziter Polymorphismus) und Hibernate unterstützt sowohl impliziten als auch expliziten Polymorphismus:
Implizite Polymorphie bedeutet, dass Instanzen der Klasse sein werden zurückgegeben von einer Abfrage, die einen Namen gibt Superklasse oder implementierte Schnittstelle oder Klasse und die Instanzen von irgendwelchen Unterklasse der Klasse wird zurückgegeben durch eine Abfrage, die die Klasse benennt selbst. Explicit Polymorphismus bedeutet Diese Klasseninstanzen werden zurückgegeben nur durch Abfragen, die explizit benennen diese Klasse. Abfragen, die den Namen Die Klasse gibt nur Instanzen von Unterklassen, die darin abgebildet sind
<class>
deklaration als a<subclass>
oder<joined-subclass>
. Für die meisten Zwecke der Standardpolymorphism="implicit"
ist angemessen. Expliziter Polymorphismus ist nützlich, wenn zwei verschiedene Klassen sind auf die gleiche Tabelle abgebildet Dies ermöglicht a "leichte" Klasse, die a enthält Teilmenge der Tabellenspalten.
Dies kann auf Klassenebene konfiguriert werden. Verwenden Sie polymorphism="explicit"
, wenn Sie XML-Mappings verwenden, siehe 5.1.3 Klasse . Verwenden Sie Hibernates @Entity
Annotation, wenn Sie Annotationen verwenden, siehe 2.4 .1. Entität Unter einem Beispiel:
Angenommen, Sie haben eine Klassenstruktur wie folgt:
%Vor% Wenn Sie alle Animal
s auswählen, sollten Sie auch alle Dog
s und Cat
s laden. Immerhin sind sie Animal
s.
Eine andere Geschichte sind die Assoziationen. Sie können Ihre Zuordnungen so erstellen, dass die Zuordnungen lazy statt eager geladen werden.
Im Grunde genommen ist dies das Standard-ORM-Vererbungsmuster, das von Hibernate als Klassenvererbung bezeichnet wird (alle Klassen sind einer einzigen Tabelle zugeordnet). Wenn Sie das ändern möchten, können Sie googlen:
- einzelne Klassenhierarchie oder Tabelle pro Klasse (dadurch wird jede Klasse einer separaten Tabelle in der Datenbank zugeordnet)
- konkrete Klasse hierarhy (dies wird nur die konkreten Implementierungen zu einer Tabelle zuordnen).
Um mehrere Joins beim Abrufen der Klassenhierarchie zu vermeiden, können Sie die SINGLE_TABLE-Hierarchiezuordnungsstrategie anwenden und dann sekundäre Tabellen für Unterklassen mit der SELECT-Abrufstrategie definieren. Dies macht jedoch Ihr "Heavy Join" -Modell zu einem "N + 1 Select" -Modell. Das Beispiel:
%Vor% Und was SQL in from Super
HQL-Abfrage getan wird:
Weitere Informationen zu diesem Ansatz und den allgemeinen Tipps zum Winterschlaf finden Sie in my Artikel .