Egyetlen entitás hozzárendelése több táblához a JPA-ban

Kitartás felső

Most jelentettem be az újat Tanulj tavaszt tanfolyam, amelynek középpontjában az 5. tavasz és a tavaszi bakancs 2 alapjai állnak:

>> ELLENŐRIZZE A FOLYAMATOT

1. Bemutatkozás

A JPA kevésbé fájdalmasá teszi a Java-alkalmazások relációs adatbázis-modelljeivel való foglalkozást. A dolgok egyszerűek, ha minden táblázatot egyetlen entitásosztályhoz rendelünk. De néha megvan az oka az entitásaink és táblázataink eltérő modellezésére:

  • Amikor logikus mezõcsoportokat akarunk létrehozni, akkor több osztályt egy táblához térképezhetünk
  • Ha öröklődésről van szó, akkor osztály hierarchiát hozzárendelhetünk egy tábla struktúrához
  • Olyan esetekben, amikor a kapcsolódó mezők több tábla között vannak elszórva, és ezeket a táblákat egyetlen osztállyal szeretnénk modellezni

Ebben a rövid bemutatóban megtudhatjuk, hogyan kezelhetjük ezt az utolsó forgatókönyvet.

2. Adatmodell

Tegyük fel, hogy éttermet működtetünk, és adatokat szeretnénk tárolni minden általunk kínált étkezésről:

  • név
  • leírás
  • ár
  • milyen allergéneket tartalmaz

Mivel sok lehetséges allergén létezik, ezt az adatkészletet össze fogjuk csoportosítani. Továbbá ezt a következő táblázatdefiníciókkal is modellezzük:

Most nézzük meg, hogyan térképezhetjük le ezeket a táblázatokat entitásokra a szokásos JPA-kommentárok használatával.

3. Több entitás létrehozása

A legkézenfekvőbb megoldás egy entitás létrehozása mindkét osztály számára.

Kezdjük azzal, hogy meghatározzuk a Étkezés entitás:

@Entity @Table (name = "meal") osztály Étkezés {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) @Column (name = "id") Hosszú id; @ Oszlop (név = "név") Karakter neve; @ Oszlop (név = "leírás") Karakterlánc leírása; @ Oszlop (név = "ár") BigDecimal ár; @OneToOne (mappedBy = "étkezés") Allergének allergénjei; // szabványos mérőeszközök és beállítók}

Ezután hozzáadjuk a Allergének entitás:

@Entity @Table (name = "allergének") osztály Allergének {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) @Column (name = "meal_id") Long mealId; @OneToOne @PrimaryKeyJoinColumn (name = "meal_id") Étkezési étkezés; @ Oszlop (név = "földimogyoró") logikai földimogyoró; @ Oszlop (név = "zeller") logikai zeller; @ Oszlop (név = "szezám_mag") logikai szezámmag; // szabványos mérőeszközök és beállítók}

A fenti példában ezt láthatjuk meal_id az elsődleges és az idegen kulcs is. Ez azt jelenti, hogy a használatával meg kell határoznunk az egy-egy kapcsolat oszlopot @PrimaryKeyJoinColumn.

Ennek a megoldásnak azonban két problémája van:

  • Mindig étkezéshez szeretnénk allergéneket tárolni, és ez a megoldás nem érvényesíti ezt a szabályt
  • Az étkezés és az allergén adatok logikusan összetartoznak - ezért érdemes ezeket az információkat ugyanabban a Java osztályban tárolni, annak ellenére, hogy több táblázatot hoztunk létre számukra

Az első probléma egyik lehetséges megoldása a @Nem nulla jegyzet a allergének mezőnk Étkezés entitás. A JPA nem engedi, hogy kitartson a Étkezés ha van egy nullaAllergének.

Ez azonban nem ideális megoldás; korlátozóbbat akarunk, ahol még arra sincs lehetőségünk, hogy megpróbáljuk kitartani a Étkezés nélkül Allergének.

4. Egyetlen entitás létrehozása a @SecondaryTable

Hozhatunk létre egy entitást, amely megadja, hogy oszlopok vannak-e a különböző táblákban a @SecondaryTable kommentár:

@Entity @Table (name = "meal") @SecondaryTable (name = "allergének", pkJoinColumns = @PrimaryKeyJoinColumn (name = "meal_id")) osztály Étkezés {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) @Column (name = "id") Hosszú id; @ Oszlop (név = "név") Karakter neve; @ Oszlop (név = "leírás") Karakterlánc leírása; @ Oszlop (név = "ár") BigDecimal ár; @ Oszlop (név = "földimogyoró", táblázat = "allergének") logikai földimogyoró; @ Oszlop (név = "zeller", tábla = "allergének") logikai zeller; @ Oszlop (név = "szezámmag", tábla = "allergének") logikai szezámmag; // szabványos mérőeszközök és beállítók}

A kulisszák mögött a JPA csatlakozik az elsődleges táblához a másodlagos táblához, és feltölti a mezőket. Ez a megoldás hasonló a @1-1 kapcsolat, de így ugyanabban az osztályban rendelkezhetünk az összes tulajdonsággal.

Fontos megjegyezniha van egy oszlopunk, amely egy másodlagos táblában van, akkor azt a -val kell megadnunk asztal érvelése @Oszlop annotáció. Ha egy oszlop szerepel az elsődleges táblázatban, akkor az asztal argumentum, mivel a JPA alapértelmezés szerint oszlopokat keres az elsődleges táblázatban.

Vegye figyelembe azt is, hogy több másodlagos táblánk is lehet, ha beágyazjuk őket @SecondaryTables. Alternatív megoldásként a Java 8-ból az entitást többször is megjelölhetjük @SecondaryTable megjegyzéseket, mivel ez megismételhető megjegyzés.

5. Kombinálás @SecondaryTable Val vel @Beágyazott

Mint láttuk, @SecondaryTable több táblázatot hozzárendel ugyanahhoz az entitáshoz. Ezt mi is tudjuk @Beágyazott és @Beágyazható ennek ellenkezőjét tegye, és egyetlen táblázatot több osztályhoz hozzárendeljen.

Lássuk, mit kapunk, ha kombinálunk @SecondaryTable val vel @Beágyazott és @ Beágyazható:

@Entity @Table (name = "meal") @SecondaryTable (name = "allergének", pkJoinColumns = @PrimaryKeyJoinColumn (name = "meal_id")) osztály Étkezés {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) @Column (name = "id") Hosszú id; @ Oszlop (név = "név") Karakter neve; @ Oszlop (név = "leírás") Karakterleírás; @ Oszlop (név = "ár") BigDecimal ár; @ Beágyazott allergén allergének; // szokásos getterek és beállítók} @Embeddable class Allergens {@Column (name = "peanuts", table = "allergens") boolean peanuts; @ Oszlop (név = "zeller", tábla = "allergének") logikai zeller; @ Oszlop (név = "szezámmag], tábla =" allergének ") logikai szezámmag; // szabványos mérőeszközök és beállítók}

Hasonló megközelítés, mint amit láttunk használni @1-1. Van azonban néhány előnye:

  • A JPA együtt kezeli a két asztalt számunkra, így biztosak lehetünk abban, hogy mindkét étkezésnél sor lesz minden étkezésre
  • Ezenkívül a kód egy kicsit egyszerűbb, mivel kevesebb konfigurációra van szükségünk

Ennek ellenére ez az egy az egyhez hasonló megoldás csak akkor működik, ha a két tábla azonos azonosítóval rendelkezik.

Érdemes megemlíteni, hogy ha újra fel akarjuk használni a Allergének osztályban, jobb lenne, ha a másodlagos táblázat oszlopait definiálnánk a Étkezés osztályban @AttributeOverride.

6. Következtetés

Ebben a rövid bemutatóban láthattuk, hogyan tudunk több táblázatot leképezni ugyanarra az entitásra a @SecondaryTable JPA kommentár.

Láttuk a kombinálás előnyeit is @SecondaryTable val vel @Beágyazott és @ Beágyazható hogy egy-egyhez hasonló kapcsolat jöjjön létre.

Szokás szerint a példák elérhetők a GitHub oldalon.

Perzisztencia alsó

Most jelentettem be az újat Tanulj tavaszt tanfolyam, amelynek középpontjában az 5. tavasz és a tavaszi bakancs 2 alapjai állnak:

>> ELLENŐRIZZE A FOLYAMATOT