Eifrige/faule Ladung im Ruhezustand

Eager/Lazy Loading In Hibernate

1. Einführung

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, welche in Hibernate verwendet werden können.

2. Maven-Abhängigkeiten

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


    org.hibernate
    hibernate-core
    5.2.2.Final

Die neueste Version von Hibernate finden Sie unterhere.

3. Eifriges und faules Laden

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

  • Eager Loading 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:

DieUserLazy 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 KlasseOrderDetail:

@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

}

EinUser kann mehrereOrderDetails haben. In eager loading strategy, if we load the User data, it will also load up all orders associated with it and will store it in a memory.

Wenn jedoch das verzögerte Laden aktiviert ist undUserLazy aufgerufen werden, werdenOrderDetail 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 ist.

4. Konfiguration laden

In diesem Abschnitt wird erläutert, wie Abrufstrategien im Ruhezustand konfiguriert werden 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

Um Eager Loading einzurichten, haben wir die ZwillingsklasseUserLazy mit dem NamenUserEager verwendet.

Im nächsten Abschnitt werden wir die Unterschiede zwischen den beiden Arten des Abrufens betrachten.

5. Unterschiede

Wie bereits erwähnt, besteht der Hauptunterschied zwischen den beiden Abrufarten darin, dass 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 werdenorderDetailSet nur initialisiert, wenn sie explizit mit einem Getter oder einer anderen Methode aufgerufen werden, wie im obigen Beispiel gezeigt:

UserLazy userLazyLoaded = users.get(3);

Bei einem eifrigen Ansatz inUserEager wird er 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 wird ausgelöst, um dieorderDetailSet zu laden.

Die Idee, Proxys oder das verzögerte Laden zu deaktivieren, 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 zum Testen der obigen Funktionalität verwendet werden:

Hibernate.isInitialized(orderDetailSet);

Nun ist es wichtig, die Abfragen zu betrachten, die in beiden Fällen generiert werden:

true

Die obige Einstellung infetching.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 derUser-Daten generiert wird:

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

Beim eifrigen Laden wurde jedoch eine Verknüpfung mitUSER_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 alleUsers generiert, was dazu führt, dass viel mehr Speicher verwendet wird als beim anderen Ansatz.

6. Vorteile und Nachteile

6.1. Faules Laden

Vorteile:

  • Anfangsladezeit viel kleiner als bei der anderen Methode

  • Geringerer Speicherverbrauch als beim anderen Ansatz

Nachteile:

  • Eine verzögerte Initialisierung kann die Leistung in unerwünschten Momenten beeinträchtigen

  • In einigen Fällen müssen Sie träge initialisierte Objekte mit besonderer Sorgfalt behandeln, oder es kommt zu einer Ausnahme

6.2. Eifriges Laden:

Vorteile:

  • Keine Auswirkungen auf die Leistung aufgrund verzögerter Initialisierung

Nachteile:

  • Lange anfängliche Ladezeit

  • Das Laden zu vieler unnötiger Daten kann die Leistung beeinträchtigen

7. Faules Laden im Ruhezustand

Hibernate applies lazy loading approach on entities and associations by providing a proxy implementation der Klassen.

Hibernate fängt Aufrufe an eine Entität ab, indem es durch einen Proxy ersetzt wird, der von der Klasse einer Entität abgeleitet ist. Wenn in unserem Beispiel eine angeforderte Information fehlt, wird sie aus einer Datenbank geladen, bevor die Steuerung an die Klassenimplementierung vonUserabgetreten wird.

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

Um mehr über das Proxy-Entwurfsmuster zu erfahren, können Sie aufhere verweisen.

8. Fazit

In diesem Artikel haben wir die beiden Haupttypen des Abrufens gezeigt, die im Ruhezustand verwendet werden.

Weiterführende Informationen finden Sie auf der offiziellen Website von Hibernate. Um den in diesem Artikel beschriebenen Code zu erhalten, schauen Sie sich bitte dieserepository an.