FetchMode hibernált állapotban

1. Bemutatkozás

Ebben a rövid bemutatóban másokat vessünk szemügyre FetchMode értékek, amelyeket a @org.hibernate.annotations.Fetch annotáció.

2. A példa beállítása

Példaként a következőket fogjuk használni Vevő csak két tulajdonsággal rendelkező entitás - azonosító és rendeléskészlet:

@Entity public class Customer {@Id @GeneratedValue private Long id; @OneToMany (mappedBy = "customer") @Fetch (value = FetchMode.SELECT) private Set megbízások = new HashSet (); // szerelők és beállítók}

Ezenkívül létrehozunk egy Rendelés entitás, amely azonosítóból, névből és a Vevő.

@Entity public class Order {@Id @GeneratedValue private Long id; privát karakterlánc neve; @ManyToOne @JoinColumn (név = "ügyfél_azonosító") magánvevő ügyfél; // szerelők és beállítók}

A következő szakaszok mindegyikében lekérjük az ügyfelet az adatbázisból, és megkapjuk az összes megrendelését:

Ügyfél ügyfél = customerRepository.findById (id) .get (); Rendelések beállítása = customer.getOrders ();

3. FetchMode.SELECT

Miénken Vevő entitás, feljegyeztük a megrendelések ingatlan a @Fetch kommentár:

@OneToMany @Fetch (FetchMode.SELECT) privát készlet rendelések;

Használunk @Fetch annak leírása, hogy a hibernátusnak miként kell lekérnie a tulajdonságot, amikor megkeresjük a Vevő.

Használata SELECT azt jelzi, hogy az ingatlant lustán kell betölteni.

Ez azt jelenti, hogy az első sor esetében:

Ügyfél ügyfél = customerRepository.findById (id) .get ();

Nem látunk csatlakozást a megrendelések táblához:

Hibernálás: válassza ki ... az ügyfélből, ahol a customer0_.id =? 

És ez a következő sorra:

Ügyfél ügyfél = customerRepository.findById (id) .get ();

Látni fogjuk a kapcsolódó megrendelések következő kérdéseit:

Hibernálás: válasszon ... abból a sorrendből, ahol a order0_.customer_id =? 

A Hibernálás FetchMode.SELECT külön lekérdezést generál mindegyikhez Rendelés hogy be kell tölteni.

Példánkban ez egy lekérdezést ad az ügyfelek betöltésére és további öt kérdést a megrendelések gyűjteményének betöltésére.

Ez az úgynevezett n + 1 kiválasztott probléma. Egy lekérdezés végrehajtása kiváltja n további lekérdezések.

3.1. @Csomó méret

FetchMode.SELECT opcionális konfigurációs kommentárral rendelkezik a @Csomó méret kommentár:

@OneToMany @Fetch (FetchMode.SELECT) @BatchSize (size = 10) private Set rendelések;

Hibernálás megpróbálja betölteni a megrendelések gyűjteményét a méret paraméter.

Példánkban csak öt rendelésünk van, tehát egy lekérdezés elegendő.

Továbbra is ugyanazt a lekérdezést fogjuk használni:

Hibernálás: válasszon ... abból a sorrendből, ahol a order0_.customer_id =?

De csak egyszer fogják futtatni. Most csak két kérdésünk van: Az egyik a Vevő egy pedig a rendelésgyűjtemény betöltésére.

4. FetchMode.JOIN

Míg FetchMode.SELECT lustán tölti a kapcsolatokat, FetchMode.JOIN lelkesen tölti be őket, mondjuk egy csatlakozással:

@OneToMany @Fetch (FetchMode.JOIN) privát Rendelések;

Ez csak egy lekérdezést eredményez mind a Vevő és övék Rendeléss:

Hibernálás: válassza ki ... az ügyfél ügyfélből0_ bal külső csatlakozási rendelés1 a customer.id = order.customer_id ahol customer.id =?

5. FetchMode.SUBSELECT

Mert a megrendelések ingatlan egy gyűjtemény, mi is felhasználhatnánk FetchMode.SUBSELECT:

@OneToMany @Fetch (FetchMode.SUBSELECT) privát Set rendelések;

Csak használni tudjuk ALVÁLASZTOTT gyűjteményekkel.

Ezzel a beállítással visszatérünk a Vevő:

Hibernálás: válasszon ... a vevőtől 

És egy lekérdezés a Rendeléss, ezúttal egy részválasztással:

Hibernálás: válasszon ... a rendelési0_ helyről, ahol a megrendelés0_.ügyfél_azonosító be van jelölve (válassza az ügyfél0_.id értéket az ügyfél ügyfél0_ értékéből)

6. FetchMode vs. FetchType

Általánosságban, FetchMode meghatározza, hogyan Hibernálás lekéri az adatokat (kiválasztással, csatlakozással vagy alszelektálással). FetchTypemásrészt meghatározza, hogy a Hibernate lelkesen vagy lustán tölti-e be az adatokat.

A kettő közötti pontos szabályok a következők:

  • ha a kód nem áll be FetchMode, az alapértelmezett CSATLAKOZIK és FetchType definíció szerint működik

  • val vel FetchMode.SELECT vagy FetchMode.SUBSELECT készlet, FetchType meghatározása szerint is működik
  • val vel FetchMode.JOIN készlet, FetchType figyelmen kívül hagyja, és a lekérdezés mindig szívesen

További információkért kérjük, olvassa el a Vágyakozó / Lusta betöltés hibernált állapotban című részt.

7. Következtetés

Ebben az oktatóanyagban megtudtuk FetchModeKülönböző értékeit, és azt is, hogyan kapcsolódnak hozzájuk FetchType.

Mint mindig, az összes forráskód elérhető a GitHubon.