Heim  >  Artikel  >  Backend-Entwicklung  >  Laden und in die Sitzung einsteigen

Laden und in die Sitzung einsteigen

巴扎黑
巴扎黑Original
2016-12-20 17:13:581302Durchsuche

1. Get unterstützt Lazy nicht, Load unterstützt Lazy.

2. Verwenden Sie get, um Daten zu laden. Wenn keine übereinstimmenden Daten vorhanden sind, wird null zurückgegeben und Load löst eine Ausnahme aus.

3. Überprüfen Sie beim Ausführen von load() zunächst, ob das aktuelle Objekt in der Sitzung vorhanden ist. Wenn dieser Datensatz nicht vorhanden ist, wird eine Ausnahme ausgelöst. Wenn get() ausgeführt wird, wird unabhängig davon, ob das aktuelle Objekt in der Sitzung vorhanden ist, direkt aus der Datenbank abgefragt. Wenn es nicht vorhanden ist, wird null zurückgegeben.

4. Die Methode „load()“ kann die Proxy-Klasseninstanz der Entität zurückgeben, während „get()“ immer nur die Entitätsklasse zurückgibt.

Beispiel abrufen:

1public void testGetMethod() {
2 Session session = null;
3 try {
4  session = HibernateUtils.getSession();
5  session.beginTransaction();
6   
7  //Sofort die SQL-Abfrage ausgeben und das Benutzerobjekt c2ff0002 laden);
9   System.out.println("user.name=" + user .getName());
10  
11   user.setName("张三");
12  session.getTransaction( );
13  }catch(Exception e) {
14  e.printStackTrace();
15  session.getTransaction().rollback();
16  }finally { >17   HibernateUtils.closeSession(session); Es gibt keinen user.getName()-Methodenaufruf Zeile 9. Wenn kein passender Datensatz vorhanden ist, wird eine Null zurückgegeben.

Beispiel für eine Lademethode:

1public void testLoadMethod() {
2 Session session = null;
3 try {
4  session = HibernateUtils.getSession(); 🎜>5   session.beginTransaction(); Dieses Objekt wird geladen (Ausgabe einer SQL-Anweisung)
9   //Das Implementierungsprinzip des verzögerten Ladens im Ruhezustand ist der Proxy-Modus
10  User user = (User)session.load(User .class, "402880d01b9bf210011b9bf2b2ff0002");
11  System.out.println("user.name=" + user.getName());
12  user.setName("李思"); session.getTransaction().commit() ;
14  }catch(Exception e) {
15   e.printStackTrace();
16   (session); 🎜>19  }
20 }

PS: Die SQL-Anweisung wurde nicht sofort ausgegeben, als 10 Codezeilen ausgeführt wurden. Da Load Lazy Loading implementiert, wird Lazy Loading nur verwendet Nur wenn das Objekt geladen und die SQL-Anweisung ausgegeben wird. Der Schlüssel besteht aus 11 Codezeilen. Wenn die ID in der Lademethode nicht mit der Datenbanktabelle verknüpft ist, wird eine ObjectNotFoundException-Ausnahme ausgegeben.

PS: Sie können Haltepunkte festlegen und Debug verwenden, um Änderungen in zugehörigen Variablen und Objekten zu verfolgen, sodass Sie die Lade- und Get-Methoden klar verstehen können.

Ruhezustand, das von der Sitzung geladene Objekt ist

Persistenter Zustand: Das Objekt stellt eine entsprechende Beziehung zum Datenbankdatensatz her und behält die Synchronisierung bei. Das Objekt ist an den Persistenzkontext gebunden und alle zukünftigen Statusänderungen und Datenänderungen unterliegen der Verwaltung der Arbeitseinheit. Dies ist der Persistenzstatus. Session.load ist die in hibernate3.2 bereitgestellte Standardmethode für verzögertes Laden. Ich denke, was geladen wird, ist ein Proxy, der auch als persistent bezeichnet werden kann (ich verstehe es so, bitte bitten Sie einen Experten, es zu korrigieren, wenn ich falsch liege). ).





Lazy Loading zu verstehen ist hilfreich, um Lazy Loading zu verstehen:

Der Lazy-Loading-Mechanismus wird vorgeschlagen, um unnötigen Leistungsaufwand zu vermeiden. Das sogenannte Lazy-Loading bedeutet, dass der Datenladevorgang nur dann durchgeführt wird, wenn die Daten tatsächlich benötigt werden. Hibernate ermöglicht das verzögerte Laden von Entitätsobjekten und das verzögerte Laden von Sammlungen. Darüber hinaus bietet Hibernate3 auch das verzögerte Laden von Eigenschaften. Im Folgenden stellen wir die Details dieser Arten des verzögerten Ladens vor.

A. Lazy Loading von Entitätsobjekten:

Wenn Sie Lazy Loading für Entitätsobjekte verwenden möchten, müssen Sie die entsprechende Konfiguration in der Zuordnungskonfigurationsdatei der Entität vornehmen, wie unten gezeigt:



……





Aktivieren Sie die Lazy-Loading-Funktion der Entität, indem Sie das Lazy-Attribut der Klasse auf true setzen . Wenn wir den folgenden Code ausführen:

User user=(User)session.load(User.class“,1“ (1)

System.out.println(user.getName ()); (2)

Beim Ausführen von (1) initiiert Hibernate keine Datenabfrage. Wenn wir zu diesem Zeitpunkt einige Debugging-Tools verwenden (z. B. das Debug-Tool von JBuilder2005), beachten Sie dies Speicher-Snapshot des Benutzerobjekts. Wir werden überrascht sein, dass das, was zu diesem Zeitpunkt zurückgegeben wird, möglicherweise ein Objekt vom Typ User$EnhancerByCGLIB$$bede8986 ist und sein Attribut null ist. Was ist los? Denken Sie daran, dass ich zuvor erwähnt habe, dass die Methode session.load() das Proxy-Klassenobjekt des Entitätsobjekts zurückgibt. Der hier zurückgegebene Objekttyp ist das Proxy-Klassenobjekt des Benutzerobjekts. Im Ruhezustand wird CGLIB verwendet, um dynamisch ein Proxy-Klassenobjekt des Zielobjekts zu erstellen. Das Proxy-Klassenobjekt enthält alle Eigenschaften und Methoden des Zielobjekts, und allen Eigenschaften wird Null zugewiesen. Anhand des vom Debugger angezeigten Speicher-Snapshots können wir erkennen, dass das tatsächliche Benutzerobjekt zu diesem Zeitpunkt im Attribut CGLIB$CALBACK_0.target des Proxy-Objekts enthalten ist. Wenn der Code bis (2) ausgeführt wird, wird user.getName( aufgerufen Zu diesem Zeitpunkt wird die Methode CGLIB$CALBACK_0.getName() tatsächlich über den von CGLIB bereitgestellten Rückrufmechanismus aufgerufen. Beim Aufruf dieser Methode prüft Hibernate zunächst, ob das Attribut CGLIB$CALBACK_0.target null ist . Wenn es nicht null ist, rufen Sie die getName-Methode des Zielobjekts auf. Wenn es leer ist, wird eine SQL-Anweisung wie diese generiert: select * from user where id='1'; Fragen Sie die Daten ab, erstellen Sie das Zielobjekt und weisen Sie es dem CGLIB-Attribut $CALBACK_0.target zu.

Auf diese Weise implementiert Hibernate das verzögerte Laden von Entitäten. Nur wenn der Benutzer tatsächlich eine Aktion zum Abrufen der Attribute des Entitätsobjekts initiiert, wird der Datenbankabfragevorgang tatsächlich initiiert. Daher wird das verzögerte Laden von Entitäten über die Zwischen-Proxy-Klasse abgeschlossen, sodass nur die Methode session.load () das verzögerte Laden von Entitäten verwendet, da nur die Methode session.load () das Proxy-Klassenobjekt der Entität zurückgibt Klasse.

B. Lazy Loading von Sammlungstypen:

Im Lazy Loading-Mechanismus ist die Anwendung von Sammlungstypen von größter Bedeutung, da sie die Leistung erheblich verbessern kann Viele Anstrengungen, einschließlich der unabhängigen Implementierung der JDK-Sammlung. In Eins-zu-Viele-Beziehungen ist die Set-Sammlung, die wir zur Aufnahme der zugehörigen Objekte definieren, nicht der Typ java.util.Set, sondern der Typ net. sf.hibernate.collection.Set-Typ Durch die Implementierung einer benutzerdefinierten Sammlungsklasse implementiert Hibernate das verzögerte Laden von Sammlungstypen. Um Lazy Loading für Sammlungstypen zu verwenden, müssen wir den Assoziationsteil unserer Entitätsklasse wie folgt konfigurieren:



…..



Arrderss"/>







Aktivieren Sie die Lazy-Loading-Funktion des Sammlungstyps, indem Sie das Lazy-Attribut des Schauen wir uns den folgenden Code an:

User user=(User)session.load(User.class“,1“);

Collection addset=user.getAddresses( (1)

Iterator it=addset.iterator(); (2)

while(it.hasNext()){

Adresse address=(Address)it.next();

System.out.println(address.getAddress());

Wenn das Programm ausgeführt wird ( 1) wird keine Abfrage nach zugehörigen Daten initiiert. Erst wenn (2) erreicht wird, beginnt der Ruhezustand basierend auf den qualifizierten Daten im Cache Finden Sie Entitätsobjekte, die die Bedingungen erfüllen.

Hier stellen wir ein neues Konzept vor – Datenindex. Als nächstes werfen wir einen Blick darauf, was ein Datenindex ist. Beim Zwischenspeichern eines Sammlungstyps im Ruhezustand wird dieser in zwei Teilen zwischengespeichert. Zuerst wird die ID-Liste aller Entitäten in der Sammlung zwischengespeichert, und dann werden die Entitätsobjekte zwischengespeichert. Die ID-Liste dieser Entitätsobjekte ist die sogenannte Daten Index. Wenn bei der Suche nach einem Datenindex der entsprechende Datenindex nicht gefunden wird, wird ein Select-SQL ausgeführt, um qualifizierte Daten abzurufen, eine Sammlung von Entitätsobjekten und Datenindizes zu erstellen, dann eine Sammlung von Entitätsobjekten zurückzugeben und die Entitätsobjekte hinzuzufügen und Datenindizes in den Cache von Hibernate. Wenn andererseits der entsprechende Datenindex gefunden wird, wird die ID-Liste aus dem Datenindex entnommen und die entsprechende Entität anhand der ID durchsucht. Wenn sie gefunden wird, wird sie aus dem Cache zurückgegeben nicht gefunden, wird eine ausgewählte SQL-Abfrage initiiert. Hier sehen wir ein weiteres Problem, das sich möglicherweise auf die Leistung auswirkt, nämlich die Caching-Strategie des Sammlungstyps. Wenn wir den Sammlungstyp wie folgt konfigurieren:



…..








Beim Sammlungstyp speichert Hibernate nur den Datenindex zwischen, nicht die Entitätsobjekte in der Sammlung. Wie oben konfiguriert, führen wir den folgenden Code aus:

User user=(User)session.load(User.class“,1“);

Collection addset=user.getAddresses();

Iterator it=addset. iterator(); 🎜>System.out.println(address.getAddress());

System.out.println(“ Zweite Abfrage…“);

Benutzer user2 =(User)session.load(User.class“,1“);

Collection it2=user2.getAddresses(); 🎜>while(it2.hasNext()){

Address address2=(Address)it2.next();

System.out.println(address2.getAddress()); >
}

Führen Sie diesen Code aus. Sie erhalten eine Ausgabe ähnlich der folgenden:

Wählen Sie * von Benutzer aus, wobei id='1';

Wählen Sie * aus Adresse, wo user_id='1';

Tianjin

Dalian

Zweite Abfrage...

Wählen Sie * aus Adresse, wo id='1';

Wählen Sie * aus der Adresse aus, wobei id='2' ;

Tianjin

Dalian

Wir sehen, dass, wenn die Abfrage zum zweiten Mal ausgeführt wird, Es werden zwei Abfrageoperationen für die Adresstabelle ausgeführt. Warum ist das so? Dies liegt daran, dass beim ersten Laden der Entität gemäß der Konfiguration der Sammlungstyp-Caching-Strategie nur der Sammlungsdatenindex zwischengespeichert wird, die Entitätsobjekte in der Sammlung jedoch nicht zwischengespeichert werden. Daher wird die Entität geladen Zum zweiten Mal fand Hibernate den Datenindex der entsprechenden Entität, konnte die entsprechende Entität jedoch laut Datenindex nicht im Cache finden, sodass Hibernate zwei ausgewählte SQL-Abfragevorgänge basierend auf dem gefundenen Datenindex initiierte Wie kann dies vermieden werden? Wir müssen auch eine Cache-Strategie für die Entitäten im Sammlungstyp angeben, daher müssen wir den Sammlungstyp wie folgt konfigurieren:



…..








Zu diesem Zeitpunkt speichert Hibernate auch die Entitäten im Sammlungstyp zwischen. Es wird eine Ausgabe ähnlich der folgenden angezeigt:

Select * from user where id='1';

Select * from address where user_id='1';

Dalian

Zweite Abfrage...

Tianjin

Dalian

Zu diesem Zeitpunkt müssen keine SQL-Anweisungen mehr basierend auf dem Datenindex abgefragt werden, da die im Sammlungstyp gespeicherten Entitätsobjekte direkt aus dem Cache abgerufen werden können.

C. Eigenschaft Lazy Loading:

In Hibernate3 wird eine neue Funktion eingeführt – das verzögerte Laden von Attributen. Dieser Mechanismus bietet ein leistungsstarkes Tool zum Abrufen leistungsstarker Abfragen. Als wir zuvor über das Lesen von Big-Data-Objekten gesprochen haben, gibt es ein Lebenslauffeld im Benutzerobjekt. Dieses Feld ist vom Typ java.sql.Clob und enthält die Lebenslaufinformationen des Benutzers. Wenn wir das Objekt laden, müssen wir es jedes Mal laden Dieses Feld muss unabhängig davon geladen werden, ob wir es wirklich benötigen, und das Lesen dieses großen Datenobjekts selbst bringt einen großen Leistungsaufwand mit sich. In Hibernate2 können wir dieses Problem nur lösen, indem wir die User-Klasse durch die granulare Leistungssegmentierung zerlegen, wie wir bereits erwähnt haben (siehe die Diskussion in diesem Abschnitt), aber in Hibernate3 können wir den Attribut-Lazy-Loading-Mechanismus verwenden Wir können die Daten dieses Feldes nur dann lesen, wenn wir dieses Feld wirklich bedienen müssen. Dazu müssen wir unsere Entitätsklasse wie folgt konfigurieren:




……



Aktivieren Sie das verzögerte Laden von Eigenschaften, indem Sie das Attribut Hibernate3 Delayed Loading verwendet einen Klassen-Enhancer, um die Klassendatei der Entitätsklasse zu erweitern. Durch die Erweiterung des Enhancers wird die Rückrufmechanismuslogik von CGLIB zur Entitätsklasse hinzugefügt. Hier können wir sehen, dass das verzögerte Laden von Attributen weiterhin erfolgt durch CGLIB realisiert. CGLIB ist ein Open-Source-Projekt von Apache. Diese Klassenbibliothek kann den Bytecode von Java-Klassen manipulieren und basierend auf dem Bytecode dynamisch Klassenobjekte erstellen, die die Anforderungen erfüllen. Basierend auf der obigen Konfiguration führen wir den folgenden Code aus:

String sql=“from User user where user.name='zx' ”

Query query=session.createQuery(sql); ( 1)

List list=query.list();

for(int i=0;i
Benutzer Benutzer = (User)list.get(i);

System.out.println(user.getName());

System.out.println(user.getResume()); 2 )

}

Wenn die Ausführung (1) erreicht, wird eine SQL-Anweisung ähnlich der folgenden generiert:

Wählen Sie ID, Alter, Name vom Benutzer aus, wobei Name= 'zx ';

Zu diesem Zeitpunkt ruft Hibernate die Felddaten ab, die allen nicht verzögerten Ladeattributen in der Benutzerentität entsprechen. Wenn die Ausführung (2) erreicht, wird eine SQL-Anweisung ähnlich der folgenden generiert :

Lebenslauf von Benutzer auswählen, wobei id='1'





1. Laden Sie einen nicht vorhandenen Datensatz
Employee Employee2 = (Employee) session.load(Employee.class, new Integer(100));
löst eine net.sf.hibernate.ObjectNotFoundException aus.
Wenn Sie diese Ausnahme nicht auslösen möchten, sollten Sie session.get(Class clazz, Serializable id);

2 verwenden. Laden Sie einen Datensatz, der in der Datenbank vorhanden ist.
1) Wenn es existiert im Cache der Sitzung, dann geben Sie die Referenz direkt zurück.
Session session = HibernateSessionFactory.currentSession();
Transaction tx = session.beginTransaction();

Employee Employee1 = new Employee();

employee1.setAge((byte)10);
employee1.setBirthDay(new Date());
employee1.setEmployeeName("HairRoot");
employee1.setGender('m');
employee1.setMarried(false);
session. save(employee1);
System.out.println(employee1);

//employ1 wurde gespeichert
Employee Employee2 = (Employee) session.load(Employee.class, new Integer(/ / *employee1.getId()*/100));
System.out.println(employee2);
tx.commit();
session.close();

can Es kann festgestellt werden, dass „Mitarbeiter1“ und „Mitarbeiter2“ dieselben Referenzen sind. Wenn Sie show_sql=true aktivieren, werden Sie auch feststellen, dass der Ruhezustand keine Select-Anweisung an die Datenbank sendet.

2) Wenn die Sitzung nicht im Cache vorhanden ist, wird sofort eine Auswahl gesendet.
Session session = HibernateSessionFactory.currentSession();

Transaction tx = session.beginTransaction();

Employee Employee = (Employee) session.load(Employee.class, new Integer(100));

System.out.println(employee);

tx.commit();
session.close();

Backend: Ruhezustand: Wählen Sie „mitarbeiter0_.id“ als „id0_“, „mitarbeiter0_.age“ als „alter0_“ , Employee0_.birthDay als BirthDay0_, Employee0_.employeeName als Employee4_0_, Employee0_.gender als Gender0_, Employee0_.married als Married0_ aus MWS_TEST_EMPLOYEE Employee0_, wobei Employee0_.id=?


Zu diesem Zeitpunkt die Die Abfrage wird eingeleitet. Der eigentliche Lesevorgang der Felddaten wird fortgesetzt.


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn