Spring Data JPA og navngivne enhedsgrafer

1. Oversigt

Kort sagt, enhedsgrafer er en anden måde at beskrive en forespørgsel i JPA 2.1 på. Vi kan bruge dem til at formulere forespørgsler med bedre resultater.

I denne vejledning lærer vi at implementere enhedsgrafer med Spring Data JPA gennem et simpelt eksempel.

2. Enhederne

Lad os først oprette en model kaldet Vare som har flere egenskaber:

@Entity public class Element {@Id privat Lang id; privat strengnavn; @OneToMany (mappedBy = "item") private Listeegenskaber = ny ArrayList (); // getters og setters}

Lad os nu definere Charakteristisk enhed:

@Entity offentlig klasse Karakteristisk {@Id privat Lang id; privat streng type; @ManyToOne (fetch = FetchType.LAZY) @JoinColumn privat vare vare; // Getters og Setters}

Som vi kan se i koden, både egenskaber felt i Vare enhed og vare felt i Egenskab enhed indlæses doven ved hjælp af hente parameter. Så, vores mål her er at indlæse dem ivrigt ved kørsel.

3. Enhedsgraferne

I Spring Data JPA kan vi definere en enhedsgraf ved hjælp af en kombination af @NamedEntityGraph og @EntityGraph kommentarer. Eller vi kan også definere ad-hoc-enhedsgrafer med bare attributPaths argument af @EntityGraph kommentar.

Lad os se, hvordan det kan gøres.

3.1. Med @NamedEntityGraph

For det første kan vi bruge JPA'er @NamedEntityGraph kommentar direkte på vores Vare enhed:

@Entity @NamedEntityGraph (name = "Item.characteristics", attributeNodes = @NamedAttributeNode ("features")) offentlig klasse Element {// ...}

Og så kan vi vedhæfte @EntityGraph kommentar til en af ​​vores arkivmetoder:

offentlig grænseflade ItemRepository udvider JpaRepository {@EntityGraph (value = "Item.characteristics") Item findByName (strengnavn); }

Som koden viser, har vi passeret navnet på enhedsgrafen, som vi har oprettet tidligere på Vare enhed, til @EntityGraph kommentar. Når vi kalder metoden, er det forespørgslen, som Spring Data vil bruge.

Standardværdien af ​​typeargumentet for @EntityGraph kommentar er EntityGraphType.FETCH. Når vi bruger dette, anvender Spring Data-modulet FetchType.EAGER strategi på de angivne attributknudepunkter. Og for andre, FetchType.LAZY strategi vil blive anvendt.

Så i vores tilfælde er egenskaber ejendom indlæses ivrigt, selvom standardhentningsstrategien for @OneToMany kommentar er doven.

En fangst her er det hvis det er defineret hente strategi er IVRIGE, så kan vi ikke ændre dens adfærd til DOVEN. Dette er designet, da de efterfølgende operationer muligvis har brug for de ivrigt hentede data på et senere tidspunkt under udførelsen.

3.2. Uden @NamedEntityGraph

Eller vi kan også definere en ad-hoc-enhedsgraf, med attributPaths.

Lad os tilføje en ad-hoc-enhedsgraf til vores Egenskaber Depot der ivrigt indlæser sin Vare forælder:

offentlig grænseflade CharacteristicsRepository udvider JpaRepository {@EntityGraph (attributePaths = {"item"}) Karakteristisk findByType (strengtype); }

Dette vil indlæse vare ejendommen til Egenskab enhed ivrigt, selvom vores enhed erklærer en lazy-loading-strategi for denne ejendom.

Dette er praktisk, da vi kan definere enhedsgrafen inline i stedet for at henvise til en eksisterende navngivet enhedsgraf.

4. Test sag

Nu hvor vi har defineret vores enhedsgrafer, skal vi oprette en test sag for at bekræfte den:

@DataJpaTest @RunWith (SpringRunner.class) @Sql (scripts = "/entitygraph-data.sql") public class EntityGraphIntegrationTest {@Autowired private ItemRepository itemRepo; @Autowired private egenskaberRegistreringsegenskaberRepo; @Test offentlig ugyldighed givenEntityGraph_whenCalled_shouldRetrunDefinedFields () {Item item = itemRepo.findByName ("Table"); assertThat (item.getId ()). er EqualTo (1L); } @Test offentlig ugyldighed givetAdhocEntityGraph_whenCalled_shouldRetrunDefinedFields () {Karakteristisk karakteristik = egenskaberRepo.findByType ("Stiv"); assertThat (character.getId ()). er EqualTo (1L); }}

Den første test bruger enhedsgrafen, der er defineret ved hjælp af @NamedEntityGraph kommentar.

Lad os se SQL genereret af dvaletilstand:

vælg element0_.id som id1_10_0_, characteri1_.id som id1_4_1_, item0_.name som navn2_10_0_, characteri1_.item_id som item_id3_4_1_, characteri1_.type som type2_4_1_, characteri1_.item_id som item_id3_4_0__, på item0_.id = characteri1_.item_id hvor item0_.name =?

Til sammenligning, lad os fjerne @EntityGraph kommentar fra arkivet og inspicer forespørgslen:

vælg item0_.id som id1_10_, item0_.name som name2_10_ fra item item0_ hvor item0_.name =?

Fra disse forespørgsler kan vi tydeligt se, at forespørgslen genereres uden @EntityGraph kommentar indlæser ingen egenskaber af Egenskab enhed. Som et resultat indlæser det kun Vare enhed.

Endelig lad os sammenligne dvale-forespørgsler fra den anden test med @EntityGraph kommentar:

vælg characteri0_.id som id1_4_0_, item1_.id som id1_10_1_, characteri0_.item_id som item_id3_4_0_, characteri0_.type som type2_4_0_, item1_.name som name2_10_1_ fra karakteristisk characteri0_ venstre ydre join item item1_ på characteri0_it. =?

Og forespørgslen uden @EntityGraph kommentar:

vælg characteri0_.id som id1_4_, characteri0_.item_id som item_id3_4_, characteri0_.type som type2_4_ fra karakteristisk characteri0_ hvor characteri0_.type =?

5. Konklusion

I denne vejledning har vi lært, hvordan man bruger JPA Entity Grafer i Spring Data. Med Spring Data, vi kan oprette flere arkivmetoder, der er knyttet til forskellige enhedsgrafer.

Eksemplerne til denne artikel er tilgængelige på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found