JPA entitásdiagram

1. Áttekintés

A JPA 2.1 bevezette az Entity Graph funkciót, mint egy kifinomultabb módszert a teljesítménybetöltés kezelésére.

Lehetővé teszi egy sablon meghatározását a kapcsolódó perzisztencia mezők csoportosításával, amelyeket be akarunk szerezni, és lehetővé teszi, hogy futás közben választhassuk ki a grafikon típusát.

Ebben az oktatóanyagban részletesebben elmagyarázzuk, hogyan kell létrehozni és használni ezt a funkciót.

2. Mit próbál megfejteni az entitásdiagram

A JPA 2.0-ig egy entitás-társítás betöltésére általában azt használtuk FetchType.LUSTA és FetchType.MOHÓ mint beolvasási stratégiák. Ez utasítja a JPA szolgáltatót, hogy töltse le a kapcsolódó társítást, vagy sem. Sajnos ez a meta konfiguráció statikus és nem teszi lehetővé a két stratégia közötti váltást futás közben.

A JPA Entity Graph fő célja ezután a futásidejű teljesítmény javítása az entitás kapcsolódó társításainak és alapmezejeinek betöltésekor.

Röviden: a JPA szolgáltató az összes grafikont egy kiválasztott lekérdezésbe tölti be, majd elkerüli a társítást több SELECT lekérdezéssel. Ez jó megközelítés az alkalmazás teljesítményének javításához.

3. A modell meghatározása

Mielőtt elkezdenénk felfedezni az Entitásdiagramot, meg kell határoznunk azokat a modellelemeket, amelyekkel dolgozunk. Tegyük fel, hogy szeretnénk létrehozni egy blogoldalt, ahol a felhasználók megjegyzést fűzhetnek és megoszthatják a bejegyzéseket.

Tehát először lesz egy Felhasználó entitás:

@Entity public class User {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) private Long id; privát karakterlánc neve; privát karakterlánc e-mail; // ...}

A felhasználó különféle bejegyzéseket oszthat meg, ezért szükségünk van a Post entitás:

@Entity public class Hozzászólás {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) private Long id; privát húr tantárgy; @OneToMany (mappedBy = "post") privát Lista megjegyzés = new ArrayList (); @ManyToOne (fetch = FetchType.LAZY) @JoinColumn private User felhasználó; // ...}

A felhasználó megjegyzést fűzhet a megosztott bejegyzésekhez is, így végül hozzáadunk egy Megjegyzés entitás:

@Entity public class Comment {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) private Long id; privát String válasz; @ManyToOne (fetch = FetchType.LAZY) @JoinColumn privát hozzászólás; @ManyToOne (fetch = FetchType.LAZY) @JoinColumn private User felhasználó; // ...}

Mint láthatjuk, a Post szervezetnek van kapcsolata a Megjegyzés és Felhasználó entitások. A Megjegyzés entitás társult a Post és Felhasználó entitások.

A cél ezután a következő grafikon betöltése különböző módokon:

Hozzászólás -> felhasználó: Felhasználó -> megjegyzések: Hozzászólások felsorolása [0]: Megjegyzés -> felhasználó: Felhasználói megjegyzések [1]: Megjegyzés -> felhasználó: Felhasználó

4. Kapcsolódó entitások betöltése a FetchType Stratégiák

A FetchType A módszer két stratégiát határoz meg az adatok lekérésére az adatbázisból:

  • FetchType.EAGER: A perzisztencia-szolgáltatónak be kell töltenie a kapcsolódó kommentált mezőt vagy tulajdonságot. Ez az alapértelmezett viselkedés @Basic, @ManyToOne, és @1-1 kommentált mezők.
  • FetchType.LAZY: A perzisztencia-szolgáltatónak az első eléréskor be kell töltenie az adatokat, de lelkesen betölthetők. Ez az alapértelmezett viselkedés @OneToMany, @ManyToMany és @ ElementCollection-kommentált mezők.

Például, amikor betöltjük a Post entitás, a kapcsolódó Megjegyzés az entitások nincsenek alapértelmezés szerint betöltve FetchType mivel @Egy a sokhoz van LUSTA. Ezt a viselkedést felülírhatjuk a FetchType nak nek MOHÓ:

@OneToMany (mappedBy = "post", fetch = FetchType.EAGER) privát lista megjegyzések = new ArrayList ();

Összehasonlításképpen, amikor betöltjük a Megjegyzés entitás, az övé Post a szülő entitás alapértelmezett módként van betöltve @ManyToOne, ami MOHÓ. Azt is választhatjuk, hogy nem töltjük be a Post entitásnak azáltal, hogy ezt az annotációt megváltoztatja LUSTA:

@ManyToOne (fetch = FetchType.LAZY) @JoinColumn (név = "post_id") privát Post poszt;

Vegye figyelembe, hogy mivel a LUSTA nem követelmény, a perzisztencia szolgáltató továbbra is betöltheti a Post lelkesen, ha akarja. Tehát a stratégia megfelelő használatához vissza kell térnünk a megfelelő perzisztencia-szolgáltató hivatalos dokumentációjához.

Mivel annotációkkal írtuk le a beolvasási stratégiánkat, definíciónk statikus, és nincs mód a váltásra LUSTA és MOHÓ futás közben.

Itt jelenik meg az Entity Graph, amint azt a következő szakaszban láthatjuk.

5. Entitásdiagram meghatározása

Entitásdiagram meghatározásához vagy használhatjuk az entitás kommentárjait, vagy pedig programozottan haladhatunk a JPA API segítségével.

5.1. Entitásdiagram meghatározása kommentárokkal

A @NamedEntityGraph Az annotáció lehetővé teszi az attribútumok megadását, amelyek akkor szerepelnek, amikor be akarjuk tölteni az entitást és a kapcsolódó társításokat.

Tehát először definiáljunk egy entitásdiagramot, amely betölti a Post és a hozzá kapcsolódó entitások Felhasználó és Megjegyzéss:

@NamedEntityGraph (name = "post-entity-graph", attributeNodes = {@NamedAttributeNode ("subject"), @NamedAttributeNode ("user"), @NamedAttributeNode ("comments"),}) @Entity public class Hozzászólás {@OneToMany (mappedBy = "post") privát lista megjegyzés = new ArrayList (); // ...}

Ebben a példában a @NévAttributeNode a gyökér entitás betöltésekor betöltendő kapcsolódó entitások meghatározása.

Most definiáljunk egy bonyolultabb entitásdiagramot, ahová szeretnénk betölteni a Felhasználós kapcsolódnak a Megjegyzéss.

Erre a célra a @NévAttributeNode algráf attribútum. Ez lehetővé teszi a nevű részgráf hivatkozását a @NévSubgraph kommentár:

@NamedEntityGraph (name = "post-entity-graph-with-comment-users", attributeNodes = {@NamedAttributeNode ("subject"), @NamedAttributeNode ("user"), @NamedAttributeNode (value = "comments", subgraph = " comments-subgraph "),}, subgraphs = {@NamesSubgraph (név =" comments-subgraph ", attributeNodes = {@NamedAttributeNode (" felhasználó ")})}}) @Entity public class Hozzászólás {@OneToMany (mappedBy =" post " ) privát lista megjegyzések = új ArrayList (); // ...}

A. Meghatározása @NévSubgraph a kommentár hasonló a @ -hozNamedEntityGraph és lehetővé teszi a kapcsolódó társítás attribútumainak megadását. Ezzel elkészíthetünk egy teljes gráfot.

A fenti példában a „post-entity-graph-with-comment-users ' grafikon, betölthetjük a Post, a kapcsolódó Felhasználó, a Hozzászólások és a Felhasználós kapcsolódnak a Hozzászólások.

Végül vegye figyelembe, hogy alternatív megoldásként hozzáadhatjuk az Entity Graph definícióját a orm.xml telepítési leíró:

  ...     ... 

5.2. Entitásdiagram meghatározása a JPA API-val

Az Entity Graph-et is meghatározhatjuk a EntityManager API az createEntityGraph () módszer:

EntityGraph entitásGraph = entitásManager.createEntityGraph (Post.osztály);

A gyökér entitás attribútumainak megadásához a addAttributeNodes () módszer.

entityGraph.addAttributeNodes ("tárgy"); entityGraph.addAttributeNodes ("felhasználó");

Hasonlóképpen, a kapcsolódó entitás attribútumainak felvételéhez használjuk a addSubgraph () egy beágyazott entitásgráf létrehozásához, majd mi a addAttributeNodes () ahogy fentebb tettük.

entitásGraph.addSubgraph ("megjegyzések") .addAttributeNodes ("felhasználó");

Most, hogy láttuk, hogyan hozható létre az Entitásdiagram, a következő szakaszban megvizsgáljuk, hogyan kell használni.

6. Az Entity Graph használata

6.1. Az entitásgrafikonok típusai

A JPA két tulajdonságot vagy tippet határoz meg, amelyek alapján a perzisztencia-szolgáltató választhatja az Entity Graph futás közbeni betöltését vagy letöltését:

  • javax.persistence.fetchgraph - Csak a megadott attribútumokat lehet lekérni az adatbázisból. Mivel ebben az oktatóanyagban a hibernált módot használjuk, megjegyezhetjük, hogy a JPA specifikációival ellentétben az attribútumok statikusan MOHÓ szintén betöltődnek.
  • javax.persistence.loadgraph - A megadott attribútumok mellett az attribútumok statikusan konfigurálva vannak MOHÓ szintén letöltésre kerülnek.

Mindkét esetben az elsődleges kulcs és az esetleges verzió mindig betöltődik.

6.2. Entitásdiagram betöltése

Különböző módokon tudjuk lekérni az Entity Graph-ot.

Kezdjük a EntityManager.find() módszer. Amint azt már bemutattuk, az alapértelmezett mód a statikus meta-stratégiákon alapul FetchType.EAGER és FetchType.LAZY.

Tehát hívjuk meg a megtalálja() módszer és ellenőrizze a naplót:

Post post = entitásManager.find (Post.osztály, 1L);

Itt található a Hibernate implementáció által biztosított napló:

válassza a post0_.id -t id1_1_0_, a post0_.subject tárgyként2_1_0_, post0_.user_id mint user_id3_1_0_ a post post0_ helyről, ahol post0_.id =?

Amint a naplóból láthatjuk, a Felhasználó és Megjegyzés az entitások nincsenek betöltve.

Ezt az alapértelmezett viselkedést felülírhatjuk a túlterheltek meghívásával megtalálja() módszer, amely a tippeket elfogadja a Térkép. Akkor megtehetjük adja meg a betölteni kívánt grafikon típusát:

EntityGraph entitGraph = entitásManager.getEntityGraph ("utáni entitás-grafikon"); Térkép tulajdonságai = új HashMap (); tulajdonságok.put ("javax.persistence.fetchgraph", entitGraph); Post post = entitásManager.find (Post.osztály, id, tulajdonságok);

Ha újra megnézzük a naplót, láthatjuk, hogy ezek az entitások már betöltődnek, és csak egy kiválasztott lekérdezésben:

válassza a post0_.id -t id1_1_0_, post0_.subject tárgyként2_1_0_, post0_.user_id mint user_id3_1_0_, megjegyzéseket1_.post_id mint post_id3_0_1_, comments1_.id mint id1_0_1_, comments1_.id mint id1_0_2_, comments1__id______________________________________________________________________________________________ 1____ .user_id mint user_id4_0_2_, user2_.id mint id1_2_3_, user2_.email mint email2_2_3_, user2_.name mint name3_2_3_ from Post post0_ bal külső csatlakozás Comment comments1_ on post0_.id = comments1_.post_id left left join user2_ on post0_.user_id = user2. id ahol post0_.id =?

Lássuk, hogyan érhetjük el ugyanezt a JPQL használatával:

EntityGraph entitásGraph = entitásManager.getEntityGraph ("post-entitás-grafikon-megjegyzés-felhasználókkal"); Post post = entitásManager.createQuery ("válasszon p-t a Post p-ből, ahol p.id =: id", Post.class) .setParameter ("id", id) .setHint ("javax.persistence.fetchgraph", entityGraph) .getSingleResult ();

És végül vessünk egy pillantást a Kritériumok API példa:

EntityGraph entitásGraph = entitásManager.getEntityGraph ("post-entitás-grafikon-hozzászólás-felhasználókkal"); CriteriaBuilder criteriaBuilder = entitásManager.getCriteriaBuilder (); CriteriaQuery criterionQuery = criterBuilder.createQuery (Post.class); Gyökérgyökér = feltételekQuery.from (Post.osztály); feltételekQuery.where (feltételekBuilder.equal (root.get ("id"), id)); TypedQuery typedQuery = entitásManager.createQuery (feltételekQuery); typedQuery.setHint ("javax.persistence.loadgraph", entityGraph); Post post = typedQuery.getSingleResult ();

Mindegyikben a gráf típusa tippként szerepel. Míg az első példában a Térkép, a két későbbi példában a setHint () módszer.

7. Következtetés

Ebben a cikkben megvizsgáltuk a JPA Entity Graph használatát egy dinamikus lekéréséhez Entitás és társulásai.

A döntést futás közben hozzák meg, amelyben a kapcsolódó társítás betöltését választjuk.

A teljesítmény nyilvánvalóan kulcsfontosságú tényező, amelyet figyelembe kell venni a JPA-entitások megtervezésekor. A JPA dokumentációja javasolja a FetchType.LAZY stratégiát, amikor csak lehetséges, és az Entity Graph-ot, amikor társítást kell betölteni.

Szokás szerint az összes kód elérhető a GitHubon.