Eifriges / faules Laden im Ruhezustand

Ausdauer oben

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs

1. Einleitung

Bei der Arbeit mit einem ORM kann das Abrufen / Laden von Daten in zwei Typen unterteilt werden: eifrig und faul.

In diesem kurzen Artikel werden wir auf Unterschiede hinweisen und zeigen, dass diese im Ruhezustand verwendet werden können.

2. Maven-Abhängigkeiten

Um den Ruhezustand zu verwenden, definieren wir zunächst die Hauptabhängigkeit in unserer Datei pom.xml :

 org.hibernate hibernate-core 5.2.2.Final 

Die neueste Version von Hibernate finden Sie hier.

3. Eifriges und faules Laden

Das erste, was wir hier diskutieren sollten, ist, was faules Laden und eifriges Laden sind:

  • Eifriges Laden ist ein Entwurfsmuster, bei dem die Dateninitialisierung vor Ort erfolgt
  • Lazy Loading ist ein Entwurfsmuster, mit dem die Initialisierung eines Objekts so lange wie möglich verschoben wird

Lassen Sie uns anhand einiger Beispiele sehen, wie dies tatsächlich funktioniert:

Die UserLazy- Klasse :

@Entity @Table(name = "USER") public class UserLazy implements Serializable { @Id @GeneratedValue @Column(name = "USER_ID") private Long userId; @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") private Set orderDetail = new HashSet(); // standard setters and getters // also override equals and hashcode }

Die OrderDetail- Klasse:

@Entity @Table (name = "USER_ORDER") public class OrderDetail implements Serializable { @Id @GeneratedValue @Column(name="ORDER_ID") private Long orderId; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name="USER_ID") private UserLazy user; // standard setters and getters // also override equals and hashcode }

Ein Benutzer kann mehrere OrderDetails haben . Wenn wir in der Strategie des eifrigen Ladens die Benutzerdaten laden , werden auch alle damit verbundenen Bestellungen geladen und in einem Speicher gespeichert .

Wenn jedoch das verzögerte Laden aktiviert ist und ein UserLazy aufgerufen wird , werden OrderDetail- Daten erst initialisiert und in einen Speicher geladen, wenn ein expliziter Aufruf erfolgt.

Im nächsten Abschnitt werden wir sehen, wie das obige Beispiel in Hibernate implementiert wird.

4. Konfiguration laden

In diesem Abschnitt werden wir uns ansehen, wie wir Abrufstrategien im Ruhezustand konfigurieren können. Wir werden Beispiele aus dem vorherigen Abschnitt wiederverwenden.

Lazy Loading kann einfach mit dem folgenden Annotation-Parameter aktiviert werden:

fetch = FetchType.LAZY

Um Eager Fetching zu verwenden, wird der folgende Parameter verwendet:

fetch = FetchType.EAGER

Zum Einrichten von Eager Loading haben wir die Doppelklasse von UserLazy namens UserEager verwendet .

Im nächsten Abschnitt werden wir uns die Unterschiede zwischen den beiden Abrufarten ansehen.

5. Unterschiede

Wie bereits erwähnt, besteht der Hauptunterschied zwischen den beiden Abrufarten in einem Moment, in dem Daten in einen Speicher geladen werden.

Schauen wir uns dieses Beispiel an:

List users = sessionLazy.createQuery("From UserLazy").list(); UserLazy userLazyLoaded = users.get(3); return (userLazyLoaded.getOrderDetail());

Beim Ansatz der verzögerten Initialisierung wird orderDetailSet nur initialisiert, wenn es explizit mit einem Getter oder einer anderen Methode aufgerufen wird, wie im obigen Beispiel gezeigt:

UserLazy userLazyLoaded = users.get(3);

Bei einem eifrigen Ansatz in UserEager wird dies jedoch sofort in der ersten Zeile des obigen Beispiels initialisiert:

List user = sessionEager.createQuery("From UserEager").list();

Zum verzögerten Laden wird ein Proxy-Objekt verwendet und eine separate SQL-Abfrage ausgelöst, um das orderDetailSet zu laden .

Die Idee, Proxys zu deaktivieren oder das Laden zu verzögern, wird im Ruhezustand als schlechte Praxis angesehen. Dies kann dazu führen, dass viele Daten aus einer Datenbank abgerufen und in einem Speicher gespeichert werden, unabhängig davon, ob dies erforderlich ist.

Die folgende Methode kann verwendet werden, um die oben genannte Funktionalität zu testen:

Hibernate.isInitialized(orderDetailSet);

Nun ist es wichtig, einen Blick auf die Abfragen zu werfen, die in beiden Fällen generiert werden:

true

Die obige Einstellung in der Datei fetching.hbm.xml zeigt die generierten SQL-Abfragen. Wenn Sie sich eine Konsolenausgabe ansehen, können Sie generierte Abfragen sehen.

Für Lazy Loading die Abfrage, die zum Laden der Benutzerdaten generiert wird :

select user0_.USER_ID as USER_ID1_0_, ... from USER user0_

Beim eifrigen Laden wurde jedoch eine Verknüpfung mit USER_ORDER hergestellt:

select orderdetai0_.USER_ID as USER_ID4_0_0_, orderdetai0_.ORDER_ID as ORDER_ID1_1_0_, orderdetai0_ ... from USER_ORDER orderdetai0_ where orderdetai0_.USER_ID=?

Die obige Abfrage wird für alle Benutzer generiert , was dazu führt, dass viel mehr Speicher verwendet wird als beim anderen Ansatz.

6. Vor- und Nachteile

6.1. Faules Laden

Vorteile:

  • Die anfängliche Ladezeit ist viel kleiner als beim anderen Ansatz
  • Weniger Speicherverbrauch als beim anderen Ansatz

Disadvantages:

  • Delayed initialization might impact performance during unwanted moments
  • In some cases you need to handle lazily-initialized objects with a special care or you might end up with an exception

6.2. Eager Loading:

Advantages:

  • No delayed initialization related performance impacts

Disadvantages:

  • Long initial loading time
  • Loading too much unnecessary data might impact performance

7. Lazy Loading in Hibernate

Hibernate applies lazy loading approach on entities and associations by providing a proxy implementation of classes.

Hibernate intercepts calls to an entity by substituting it with a proxy derived from an entity’s class. In our example, when a requested information is missing, it will be loaded from a database before control is ceded to the User class implementation.

Es sollte auch beachtet werden, dass, wenn die Zuordnung als Sammlungsklasse dargestellt wird (in den obigen Beispielen als Set orderDetailSet dargestellt ), ein Wrapper erstellt und eine ursprüngliche Sammlung ersetzt wird.

Weitere Informationen zum Proxy-Entwurfsmuster finden Sie hier.

8. Fazit

In diesem Artikel haben wir Beispiele für die beiden Hauptarten des Abrufs gezeigt, die im Ruhezustand verwendet werden.

Informationen zu fortgeschrittenen Kenntnissen finden Sie auf der offiziellen Website von Hibernate. Um den in diesem Artikel beschriebenen Code zu erhalten, schauen Sie sich bitte dieses Repository an.

Persistenz unten

Ich habe gerade den neuen Learn Spring- Kurs angekündigt , der sich auf die Grundlagen von Spring 5 und Spring Boot 2 konzentriert:

>> Überprüfen Sie den Kurs