1. Vererbungszuordnung
Vererbung ist ein wichtiges objektorientiertes Merkmal. Es implementiert die Verwendung von Code und hat auch eine Vererbungsbeziehung im Beziehungsmodell. Diese Vererbungsbeziehung kann tatsächlich als Aufzählungsbeziehung angesehen werden. Viele Subtypen können in einem Typ aufgezählt werden. Diese Subtypen bilden eine Vererbungsbeziehung mit dem übergeordneten Objekt. Die meisten Aufzählungen, die aufgezählt werden können, können als Vererbungskarte angesehen werden. Daher kann diese Aufzählungsbeziehung als Vererbungskarte angesehen werden. Zum Beispiel sind Tiere eine abstrakte Klasse, die die Elternklasse anderer Tiere, Schweine, Katzen usw. ist, und sie sind eine Erbschaftsbeziehung, wie in der folgenden Abbildung gezeigt:
Diese Vererbungszuordnung erzeugt eine Tabelle, nachdem sie in ein relationales Modell konvertiert wurde. Wie unterscheidet diese Tabelle zwischen diesen beiden Typen? Verwenden Sie relationale Felder. Sie müssen der Tabelle Typfelder hinzufügen und Schlüsselwörter verwenden, um den Typ des Objekts anzugeben. Daher lautet die Tabellenstruktur, die dem Objektmodell in der obigen Abbildung entspricht, wie folgt:
Beim Generieren der Tabellenstruktur müssen Sie den entsprechenden Feldtyp hinzufügen, sodass Sie der Zuordnungsdatei den entsprechenden Kartendiskriminator hinzufügen müssen. Hier müssen Sie das Attribut für Diskriminatorwerte verwenden.
1. Klassendateien
Es besteht keine Notwendigkeit, in Klassendateien aufmerksam zu machen, sondern nur auf die Vererbungsbeziehung zwischen ihnen beim Schreiben zu achten.
Listing: Animal Class Code, Sie müssen nur grundlegende Eigenschaften hinzufügen.
Paket com.src.hibernate; public class Animal {// id nummer private int id; public int getid () {return id; } public void setId (int id) {this.id = id; } // Name des privaten String -Namens; public String getName () {return name; } public void setName (String -Name) {this.name = name; } // Gender Private Boolean Sex; public boolean iSsex () {Sex zurückgeben; } public void setsex (boolean sex) {this.sex = sex; }}Listing 2: Vogel- und Schweineklassen, fügen Sie grundlegende Eigenschaften hinzu und erben Sie Tierklassen.
Paket com.src.hibernate; Public Class Bird erweitert das Tier {// Höhe private int Höhe; public int getheight () {return height; } public void setheight (int Höhe) {this.height = Höhe; }} Paket com.src.hiberNate; Public Class Pig erweitert das Tier {// Gewicht Private int Gewicht; public int GetWeight () {Return Gewicht; } public void setWeight (int Gewicht) {this.weight = Gewicht; }} 2. Kartendateien
Die entsprechende Zuordnung muss zur Zuordnungsdatei hinzugefügt werden. Das Modell muss nur eine Zuordnungsdatei hinzugefügt werden, da nur eine Tabelle generiert wird. Die entsprechende Unterklasse -Zuordnung wird der Zuordnungsdatei hinzugefügt. Verwenden Sie das <Subclass> -Tag, und der Diskriminatorwert wird dem Tag hinzugefügt. Diese Diskriminatoreigenschaft gibt wie folgt an, welcher Typ beim Schreiben von Daten in der Datenbank geschrieben wird:
<? table = "t_animal"> <id name = "id"> <generator // id> <!-Fügen Sie ein Authentifizierungs-Tag hinzu und muss nach der ID platziert werden-> <Diskriminator column = "Typ"/> <Eigenschaft name = "name"/> <Eigenschaft name = "sex" type name = "wight"/> </subclass> <subclass name = "com.src.hibernate.bird" Diskriminator-Value = "B"> <Eigenschaft name = "Höhe"/> </subklasse> </class> </hibernate-mapping>
3. Analyseergebnisse
Die generierte MySQL -Datenbanktabelle fügt nicht nur die grundlegenden Attribute von Tier hinzu, sondern auch die Eigenschaften von Schwein und Vogel. Da die hinzugefügten Attribute in der Zuordnungsdatei mit <subclass> geschrieben werden und die entsprechenden Diskriminatorattribute ebenfalls hinzugefügt werden, werden die entsprechenden Diskriminatorspalten zur Datenbank hinzugefügt. Die erzeugte Tabellenstruktur lautet wie folgt:
2. Datenbetrieb
1. Schreiben Sie Daten
Beim Durchführen von Daten zum Lesen und Schreiben von Daten müssen Sie auf die Verwendung von Operationen in der Klasse achten.
public void testsave () {session session = null; Versuchen Sie {// Sitzungsobjekt Session = hibernateUtils.getSession (); // Transaktionssitzung öffnen.BeginTransaction (); Pig Pig = New Pig (); Pig.SetName ("Little Pig"); pig.setSex (true); Pig.Setweight (200); Sitzung.Save (Schwein); Bird Bird = New Bird (); Bird.SetName ("Xiaoniao"); Bird.SetSex (True); Bird.Seteight (100); Sitzung.Save (Bird); Session.Gettransaction (). commesent (); } catch (Ausnahme e) {e.printstacktrace (); Session.Gettransaction (). Rollback (); } endlich {HibernateUtils.Closession (Sitzung); }}2. polymorphe Abfrage und HQL
Die grundlegende Abfragemethode erfordert nur die Verwendung von Last- und Abholmethoden. Hier konzentrieren wir uns auf polymorphe Abfrage. Polymorphe Abfrage bedeutet, dass Hibernate Instanz verwenden kann, um ihre tatsächliche Art von Objekt beim Laden eines Objekts zu identifizieren, damit es sich um eine polymorphe Abfrage handelt.
HINWEIS: Polymorphe Abfragen unterstützen nicht faulen Laden. Wenn Sie die Lastmethode verwenden, müssen Sie das faule Laden in der Zuordnungsdatei auf False einstellen.
3. Lastverzögerungsbelastung
Laden unterstützt faulen Laden. Beim Laden von Objekten erzeugt es tatsächlich den Stellvertreter des Objekts. Bei Verwendung polymorpher Abfragen müssen Sie daher das faule Laden in der Zuordnungsdatei wie folgt einstellen:
<? table = "t_animal" Lazy = "false"> <id name = "id"> <generator // id> <!-Fügen Sie ein Authentifizierungs-Tag hinzu und muss nach der ID platziert werden-> <Diskriminator-Spalten = "Typ"/> <Eigenschaft name = "name"/> <Property name = "sex" type Diskriminator-value = "p"> <Eigenschaft name = "Gewicht"/> </subclass> <subclass name = "com.src.hibernate.bird" Diskriminator-Value = "B"> <Eigenschaft Name = "Größe"/> </subclass> </class> </hiebnate-mapping>
Last -Lastmethode, unter Verwendung von Last zum Laden, unterstützt dieses Beispiel polymorphe Abfragen und setzen Sie das verzögerte Laden in die Konfigurationsdatei auf FALS.
public void testload () {session session = null; try {session = hibernateUtils.getSession (); Sitzung.BeginTransaction (); Animal ANI = (Animal) Sitzung.load (Animal.Class, 1); System.out.println (ani.getName ()); // Da die Last standardmäßig faul unterstützt, sehen wir den Proxy von Animal //, sodass Instanz das wahre Typ Schwein nicht identifizieren kann. } else {System.out.println ("Ich bin kein Schwein!"); } Session.getTransaction (). commit (); } catch (Ausnahme e) {e.printstacktrace (); Session.Gettransaction (). Rollback (); } endlich {HibernateUtils.Closession (Sitzung); }} 4.HQL -Abfrage
HQL unterstützt polymorphe Abfragen, was hauptsächlich darauf zurückzuführen ist, dass die Abfrage ein echtes Objekt ist und keinen Proxy zurückgibt. Daher unterstützt HQL polymorphe Abfragen. Bei der Abfrage müssen Sie außerdem darauf achten, dass die Tabellennamen in der Abfrageanweisung, sondern die Klassennamen verwendet werden. Hibernate wird es dem entsprechenden Tabellennamen gemäß dem Klassennamen wie folgt zuordnen:
public void testload5 () {session session = null; try {session = hibernateUtils.getSession (); Sitzung.BeginTransaction (); List <Anim> list = session.createquery ("From Animal"). List (); für (iterator iter = list.iterator (); iter.hasnext ();) {Animal a = (Tier) iter.Next (); if (ein Instanz von Schwein) {System.out.println ("Ich bin ein Schwein!"); } else {System.out.println ("Ich bin kein Schwein!"); }} Session.getTransaction (). commesent (); } catch (Ausnahme e) {e.printstacktrace (); Session.Gettransaction (). Rollback (); } endlich {HibernateUtils.Closession (Sitzung); }}Abfrageergebnisse:
Hibernate: Wählen Sie Animal0_.id als id0_, Animal0_.name als name0_, Animal0_.sex as sex0_, Animal0_.gewicht als Gewicht0_, Animal0_.height AS HIGH0_, Animal0_typ als Typ0_ von t_animal Animal0_ I am Schwein! Ich bin kein Schwein! Ich bin ein Ferkel! Ich bin kein Schwein!
3. Drei Strategien zur Erbschaftskartierung
1. Tabelle pro Klassenhierarchie
Angenommen, wir haben eine Schnittstellenzahlung und ihre verschiedenen Implementierungsklassen: KreditCards, Cashpayment und ChequePayment. Dann lautet der Zuordnungscode "Tabelle pro Klasse Hierarchie" wie folgt:
<class name = "payment" table = "payment"> <id name = "id" type = "long" column = "payment_id"> <generator/> </id> <diskriminator column = "payment_type" type = "String"/> <Eigentum name = "Betrag" column = "botschaft"/> ... <subclassname = "creditCardpayment" diskriminer-Value = "’ credit column = "cctype"/> ... </subclass> <subclass name = "CashPayment" Diskriminator-value = "Cash"> ... </subclass> <subclass name = "ChequePayment" Diskriminator-value = "Check"> ... </subclass> </class> </class> </class> Class>
Um diese Strategie zu übernehmen, ist nur eine Tabelle erforderlich. Es hat eine große Einschränkung: Es erfordert, dass Felder, die durch Unterklassen wie CCType definiert sind, keine Nullbeschränkungen haben können.
2. Eine Tabelle pro Unterklasse
Für die Klassen im obigen Beispiel wird die Zuordnungsstrategie von "eine Tabelle pro Unterklasse" übernommen, und der Code lautet wie folgt:
<class name = "payment" table = "payment"> <id name = "id" type = "long" column = "payment_id"> <generator/> </id> <Property name = "palbum" column = "palg"/> ... <SeN-subclass name = "creditCardPayment" table = "credit_payment"> <key columne name = "cashPayment" table = "bash_payment"> <key column = "payment_id"/> <Eigenschaft name = "creditCardtype" column = "cctype"/> ... </angeschlossene Subklasse> <Joinde-Subclass Name = "Chequepayment" table "table_payment> </klasse> </areD-Subs.
Es sind vier Tische erforderlich. Die drei Unterklassentabellen sind mit der Superklassentabelle über Primärschlüssel verbunden (so dass das Beziehungsmodell tatsächlich eins zu eins ist).
3. Jede Unterklasse hat eine Tabelle (Tabelle pro Unterklasse) und verwenden Sie den Diskriminator
Beachten Sie, dass für die Zuordnungsstrategie "eine Tabelle pro Unterklasse" die Hibernate -Implementierung keine Diskriminatorfelder erfordert, während andere Objekt-/Relational -Mapping -Tools eine Implementierungsmethode verwenden, die sich als Hibernate unterscheidet, für die eine Typ -Diskriminator -Spalte in der Superklasse -Tabelle erforderlich ist. Die von Hibernate angewandte Methode ist schwieriger zu implementieren, aber aus Sicht der Beziehungen (Datenbanken) ist sie korrekter. Wenn Sie bereit sind, die Strategie "eine Tabelle pro Unterklasse" mit Unterscheidungsfeldern zu verwenden, können Sie <Subclass> mit <Johne> wie folgt verwenden:
<class name = "payment" table = "payment"> <id name = "id" type = "long" column = "payment_id"> <generator/> </id> <diskriminator column = "payment_type" type = "String"/> <Eigentum name = "Betrag" column = "palzing"/> ... <subclass-table = "creditCardpayment" creditCardpayment "diskriminer-Value-Value =" yocary "yocarment" yocarment "yocary" credit <Property name = "creditCardType" column = "cctype"/> ... </join> </subclass> <subclass name = "CashPayment" Diskriminator-Value = "bash"> <join-table = "bash_Payment"> ... </join> </subclass> <subclasse name = "choquepayment" conequepayment "diskriminator-value- table = "Cheque_Payment" fetch = "select"> ... </join> </subclass> </class> </class>
Die optionale Deklaration Fetch = "Select" wird verwendet, um den Winterschlaf zu sagen, dass bei der Abfragung von Superklassen keine externe Verbindung verwenden, um die Daten der Unterklasse ChequePayment zu erfassen.