Egyetlen entitás hozzárendelése több táblához a JPA-ban
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 FOLYAMATOT1. 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ó