FetchMode in slaapstand

1. Inleiding

In deze korte tutorial kijken we naar verschillende FetchMode waarden die we kunnen gebruiken in de @org.hibernate.annotations.Fetch annotatie.

2. Het voorbeeld opstellen

Als voorbeeld gebruiken we het volgende Klant entiteit met slechts twee eigenschappen - een id en een set orders:

@Entity openbare klasse Klant {@Id @GeneratedValue privé Lange id; @OneToMany (mappedBy = "klant") @Fetch (waarde = FetchMode.SELECT) privé Set orders = nieuwe HashSet (); // getters en setters}

We maken ook een Bestellen entiteit bestaande uit een id, een naam en een verwijzing naar het Klant.

@Entity openbare klasse Order {@Id @GeneratedValue privé Lange id; private String naam; @ManyToOne @JoinColumn (name = "customer_id") particuliere klant-klant; // getters en setters}

In elk van de volgende secties halen we de klant uit de database en halen we al zijn bestellingen op:

Klant klant = customerRepository.findById (id) .get (); Stel bestellingen in = customer.getOrders ();

3. FetchMode.SELECT

Op onze Klant entiteit hebben we de bestellingen eigendom met een @Fetch annotatie:

@OneToMany @Fetch (FetchMode.SELECT) privé Stel bestellingen in;

We gebruiken @Fetch om te beschrijven hoe Hibernate de eigenschap moet ophalen wanneer we een Klant.

Gebruik makend van SELECTEER geeft aan dat de eigenschap lui moet worden geladen.

Dit betekent dat voor de eerste regel:

Klant klant = customerRepository.findById (id) .get ();

We zien geen join met de besteltafel:

Slaapstand: selecteer ... van klant waar customer0_.id =? 

En dat voor de volgende regel:

Klant klant = customerRepository.findById (id) .get ();

We zullen volgende vragen zien voor de gerelateerde bestellingen:

Slaapstand: selecteer ... van bestelling waar order0_.customer_id =? 

De Slaapstand FetchMode.SELECT genereert voor elk een aparte query Bestellen dat moet worden geladen.

In ons voorbeeld geeft dat één vraag om de klanten te laden en vijf extra vragen om de orderverzameling te laden.

Dit staat bekend als de n + 1 selecteer probleem. Het uitvoeren van één query wordt geactiveerd n aanvullende vragen.

3.1. @Seriegrootte

FetchMode.SELECT heeft een optionele configuratie-annotatie met de @Seriegrootte annotatie:

@OneToMany @Fetch (FetchMode.SELECT) @BatchSize (size = 10) privé Stel bestellingen in;

Slaapstand zal proberen om de orderverzameling in batches te laden die zijn gedefinieerd door de grootte parameter.

In ons voorbeeld hebben we slechts vijf bestellingen, dus één vraag is voldoende.

We zullen nog steeds dezelfde zoekopdracht gebruiken:

Slaapstand: selecteer ... van bestelling waar order0_.customer_id =?

Maar het zal maar één keer worden uitgevoerd. Nu hebben we slechts twee vragen: een om het Klant en een om de orderverzameling te laden.

4. FetchMode.JOIN

Terwijl FetchMode.SELECT laadt relaties lui, FetchMode.JOIN laadt ze gretig, zeg maar via een join:

@OneToMany @Fetch (FetchMode.JOIN) privé Stel bestellingen in;

Dit resulteert in slechts één zoekopdracht voor beide Klant en hun Bestellens:

Slaapstand: selecteer ... van klant customer0_ links buiten voeg order order1 op customer.id = order.customer_id waar customer.id =?

5. FetchMode.SUBSELECT

Omdat de bestellingen eigendom is een verzameling, we kunnen er ook gebruik van maken FetchMode.SUBSELECT:

@OneToMany @Fetch (FetchMode.SUBSELECT) privé Stel bestellingen in;

We kunnen alleen gebruiken ONDERKIES met collecties.

Met deze setup gaan we terug naar één query voor de Klant:

Slaapstand: selecteer ... van klant customer0_ 

En een vraag voor de Bestellens, deze keer met een subselectie:

Slaapstand: selecteer ... van order order0_ waar order0_.customer_id in (selecteer customer0_.id van klant customer0_)

6. FetchMode vs. FetchType

Over het algemeen, FetchMode definieert hoe Slaapstand haalt de gegevens op (door selecteren, samenvoegen of subselecteren). FetchType, aan de andere kant, bepaalt of Hibernate gegevens gretig of lui zal laden.

De exacte regels tussen deze twee zijn als volgt:

  • als de code niet is ingesteld FetchMode, de standaard is WORD LID en FetchType werkt zoals gedefinieerd

  • met FetchMode.SELECT of FetchMode.SUBSELECT set, FetchType werkt ook zoals gedefinieerd
  • met FetchMode.JOIN set, FetchType wordt genegeerd en een vraag is altijd gretig

Raadpleeg Eager / Lazy Loading In Hibernate voor meer informatie.

7. Conclusie

In deze tutorial hebben we geleerd over FetchMode‘S verschillende waarden en ook hoe ze verband houden FetchType.

Zoals altijd is alle broncode beschikbaar op GitHub.