A Közös Parlamenti Közgyűlésben állandó Enums

Java Top

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 2.0-s és újabb verzióiban nincs kényelmes módszer az Enum-értékek leképezésére egy adatbázis oszlopba. Minden opciónak megvannak a maga korlátai és hátrányai. Ezek a kérdések elkerülhetők a JPA 2.1 használatával. jellemzők.

Ebben az oktatóanyagban megvizsgáljuk azokat a különféle lehetőségeket, amelyek fennállnak a JPA használatával egy adatbázisban. Ismertetjük előnyeiket és hátrányaikat, valamint egyszerű kód példákat adunk.

2. Használata @ Számlálva Megjegyzés

A leggyakoribb lehetőség egy enum érték leképezésére a JPA-ban az adatbázis-reprezentációból a 2.1 előtt. az @ Számlálva annotáció. Így utasíthatjuk a JPA szolgáltatót, hogy konvertáljon egy enumot annak rendjébe vagy Húr érték.

Ebben a szakaszban megvizsgáljuk mindkét lehetőséget.

De először hozzunk létre egy egyszerűt @Entity amit az egész oktatóanyagban használni fogunk:

@Entity public class Article {@Id private int id; privát húr cím; // szabványos kivitelezők, mérőeszközök és beállítók}

2.1. Rendelési érték leképezése

Ha tesszük a @Enumerated (EnumType.ORDINAL) megjegyzés az enum mezőben, a JPA a Enum.ordinal () érték, ha egy adott entitást megtart az adatbázisban.

Bemutatjuk az első felsorolást:

public enum Állapot {NYITVA, ÁTTEKINTÉS, JÓVÁHAGYOTT, ELutasított; }

Ezután tegyük hozzá a Cikk osztály és jegyezd fel vele @Enumerated (EnumType.ORDINAL):

@Entity public class Article {@Id private int id; privát húr cím; @ Megszámolt (EnumType.ORDINAL) privát állapot státusz; }

Most, amikor kitart egy Cikk entitás:

Cikkcikk = új cikk (); cikk.setId (1); article.setTitle ("sorszám címe"); article.setStatus (Status.OPEN); 

A JPA a következő SQL utasítást indítja el:

illessze be a cikkbe (állapot, cím, id) értékeket (?,?,?) kötési paraméter [1], mint [INTEGER] - [0] kötési paraméter [2], mint [VARCHAR] - [rendes cím] kötési paraméter [3] mint [INTEGER] - [1]

Az ilyen típusú leképezéssel akkor merül fel probléma, ha módosítanunk kell az enumunkat. Ha új értéket adunk a közepén vagy átrendezzük az enum sorrendjét, akkor megszakítjuk a meglévő adatmodellt.

Az ilyen problémákat nehéz lehet felfogni, és problémás is megoldani őket, mivel az összes adatbázis-rekordot frissítenünk kellene.

2.2. Karaktersorozat értéke

Hasonlóképpen, a JPA a Enum.name () érték egy entitás tárolásakor, ha a feliratmezőt annotáljuk @Enumerated (EnumType.STRING).

Készítsük el a második felsorolást:

public enum Típus {BELSŐ, KÜLSŐ; }

És tegyük hozzá a sajátunkhoz Cikk osztály és jegyezd fel vele @Enumerated (EnumType.STRING):

@Entity public class Article {@Id private int id; privát húr cím; @ Megszámolt (EnumType.ORDINAL) privát állapot státusz; @Enumerated (EnumType.STRING) private Type type; }

Most, amikor kitart egy Cikk entitás:

Cikkcikk = új cikk (); cikk.setId (2); article.setTitle ("karakterlánc címe"); article.setType (Type.EXTERNAL);

A JPA végrehajtja a következő SQL utasítást:

beszúrás a cikkbe (állapot, cím, típus, id) értékek (?,?,?,?) kötési paraméter [1] [INTEGER] - [null] kötési paraméter [2] mint [VARCHAR] - [karakterlánc cím] kötés paraméter [3] mint [VARCHAR] - [KÜLSŐ] kötési paraméter [4] mint [INTEGER] - [2]

Val vel @Enumerated (EnumType.STRING), biztonságosan hozzáadhatunk új enum értékeket vagy megváltoztathatjuk az enum sorrendjét. Azonban egy enum érték átnevezése továbbra is megsérti az adatbázis adatait.

Ezenkívül, bár ez az adatábrázolás sokkal jobban olvasható a @Enumerated (EnumType.ORDINAL) opció, a szükségesnél sokkal több helyet is fogyaszt. Ez jelentős kérdésnek bizonyulhat, ha nagy mennyiségű adattal kell foglalkoznunk.

3. Használata @PostLoad és @PrePersist Megjegyzések

Egy másik lehetőség, amellyel az adatbázisban lévő állandó számlákkal kell megküzdenünk, az a standard JPA visszahívási módszerek használata. Feltérképezhetjük az enumokat oda-vissza a @PostLoad és @PrePersist események.

Az ötlet az, hogy egy entitásban két attribútum legyen. Az első egy adatbázis értékéhez van hozzárendelve, a második pedig a @ Átmeneti mező, amely valós enum értéket tartalmaz. A tranziens attribútumot ezután az üzleti logikai kód használja.

A koncepció jobb megértése érdekében hozzunk létre egy új listát, és használjuk azt int érték a leképezési logikában:

közvélemény elsőbbsége {LOW (100), MEDIUM (200), HIGH (300); privát int elsőbbség; privát Prioritás (int prioritás) {this.priority = prioritás; } public int getPriority () {return prior; } nyilvános statikus prioritása (int prioritás) {return Stream.of (Prioritás.értékek ()) .filter (p -> p.getPriority () == prioritás) .findFirst () .vagyElseThrow (IllegalArgumentException :: új); }}

Hozzáadtuk a Prioritás. () módszer megkönnyítése érdekében a Kiemelten fontos annak alapján int érték.

Most, hogy használni a mi Cikk osztályban hozzá kell adnunk két attribútumot és végre kell hajtanunk a visszahívási módszereket:

@Entity public class Article {@Id private int id; privát húr cím; @ Megszámolt (EnumType.ORDINAL) privát állapot státusz; @Enumerated (EnumType.STRING) private Type type; @Basic private int priorityValue; @ Átmeneti privát prioritás; @PostLoad void fillTransient () {if (priorityValue> 0) {this.priority = Priority.of (priorityValue); }} @PrePersist void fillPersistent () {if (prioritás! = Null) {this.priorityValue = prioritás.getPriority (); }}}

Most, amikor kitart egy Cikk entitás:

Cikkcikk = új cikk (); cikk.setId (3); article.setTitle ("visszahívási cím"); article.setPriority (Prioritás.HIGH);

A JPA a következő SQL lekérdezést indítja el:

illessze be a cikkbe (prioritásérték, állapot, cím, típus, azonosító) értékeket (?,?,?,?,?) kötelező paraméter [1] mint [INTEGER] - [300] kötési paraméter [2] mint [INTEGER] - [ null] kötési paraméter [3] mint [VARCHAR] - [visszahívási cím] kötési paraméter [4] mint [VARCHAR] - [null] kötési paraméter [5] mint [INTEGER] - [3]

Annak ellenére, hogy ez a lehetőség nagyobb rugalmasságot biztosít számunkra az adatbázis-érték ábrázolásának megválasztásában a korábban leírt megoldásokhoz képest, ez nem ideális. Csak nem helyes, ha két attribútum egyetlen entitást jelent. Továbbá, ha ilyen típusú leképezést használunk, akkor nem tudjuk használni az enum értékét a JPQL lekérdezésekben.

4. A JPA használata 2.1 @Converter Megjegyzés

A fent bemutatott megoldások korlátozásainak leküzdésére a JPA 2.1 kiadás új szabványosított API-t vezetett be, amely felhasználható az entitásattribútum átalakítására adatbázis-értékre és fordítva. Csak annyit kell tennünk, hogy létrehozunk egy új osztályt, amely megvalósítja javax.persistence.AttributeConverter és azzal jegyezd fel @Converter.

Lássunk egy gyakorlati példát. De először, mint általában, létrehozunk egy új önt:

public enum kategória {SPORT ("S"), ZENE ("M"), TECHNOLÓGIA ("T"); privát karakterlánc kód; privát kategória (karakterlánc kód) {this.code = code; } public String getCode () {visszatérési kód; }}

Hozzá kell adnunk a Cikk osztály:

@Entity public class Article {@Id private int id; privát húr cím; @ Megszámolt (EnumType.ORDINAL) privát állapot státusz; @Enumerated (EnumType.STRING) private Type type; @Basic private int priorityValue; @ Átmeneti privát prioritás; privát kategória kategória; }

Most hozzunk létre egy újat CategoryConverter:

@Converter (autoApply = true) public class CategoryConverter implementálja az AttributeConverter {@Orride public String convertToDatabaseColumn (Kategória kategória) {if (kategória == null) {return null; } return category.getCode (); } @A nyilvános kategória felülbírálása convertToEntityAttribute (String kód) {if (code == null) {return null; } return Stream.of (Category.values ​​()) .filter (c -> c.getCode (). egyenlő (kód)) .findFirst () .orElseThrow (IllegalArgumentException :: new); }}

Beállítottuk a @ConverterÉrtéke autoApply nak nek igaz hogy a JPA automatikusan alkalmazza a konverziós logikát az a összes leképezett attribútumára Kategória típus. Ellenkező esetben fel kell tennünk a @Converter annotáció közvetlenül az entitás mezőjében.

Most tartsunk fenn egy Cikk entitás:

Cikkcikk = új cikk (); cikk.setId (4); article.setTitle ("konvertált cím"); article.setCategory (Kategória.ZENE);

Ezután a JPA végrehajtja a következő SQL utasítást:

beszúrás a cikkbe (kategória, prioritásérték, állapot, státusz, cím, típus, id) értékek (?,?,?,?,?,?) Átalakított érték kötéskor: ZENE -> M kötési paraméter [1] mint [VARCHAR] - [ M] kötési paraméter [2] mint [INTEGER] - [0] kötési paraméter [3] mint [INTEGER] - [null] kötési paraméter [4] mint [VARCHAR] - [átalakított cím] kötési paraméter [5] mint [VARCHAR ] - [null] kötési paraméter [6] mint [INTEGER] - [4]

Mint láthatjuk, egyszerűen beállíthatjuk a saját szabályainkat, amelyek szerint az enumokat megfelelő adatbázis-értékre konvertáljuk, ha a AttributeConverter felület. Ezenkívül biztonságosan hozzáadhatunk új enum értékeket vagy megváltoztathatjuk a meglévőket anélkül, hogy feltörnénk a már fennmaradt adatokat.

Az átfogó megoldás egyszerűen megvalósítható, és kezeli az előző szakaszokban bemutatott lehetőségek összes hátrányát.

5. Enums használata JPQL-ben

Lássuk, milyen egyszerű enumokat használni a JPQL lekérdezésekben.

Mindet megtalálni Cikk entitások Kategória.SPORT kategóriában a következő állítást kell végrehajtanunk:

Karakterlánc jpql = "válasszon ki egy a cikkből, ahol a.kategória = com.baeldung.jpa.enums.Category.SPORT"; Lista cikkek = em.createQuery (jpql, Article.class) .getResultList ();

Fontos megjegyezni, hogy ebben az esetben teljesen minősített enum nevet kell használnunk.

Természetesen nem korlátozódunk statikus lekérdezésekre. Teljesen legális a megnevezett paraméterek használata:

Karakterlánc jpql = "válasszon ki egy a cikkből, ahol a.kategória =: kategória"; TypedQuery lekérdezés = em.createQuery (jpql, cikk.osztály); query.setParameter ("kategória", Kategória.TECHNOLÓGIA); Cikkek felsorolása = query.getResultList ();

A fenti példa a dinamikus lekérdezések kialakításának nagyon kényelmes módját mutatja be.

Ezenkívül nem kell teljesen minősített neveket használnunk.

6. Következtetés

Ebben az oktatóanyagban az adatbázisban szereplő enum értékek fennmaradásának különböző módjait ismertettük. Bemutattuk azokat a lehetőségeinket, amelyek a JPA 2.0-s és újabb verzióiban történő használatakor rendelkezésre állnak, valamint egy új API-t, amely a JPA 2.1-es és újabb verzióiban elérhető.

Érdemes megjegyezni, hogy nem csak ezek a lehetőségek állnak rendelkezésre a közös parlamenti közgyűlésben szereplő összegek kezelésére. Néhány adatbázis, például a PostgreSQL, külön oszloptípust biztosít az enum értékek tárolására. Az ilyen megoldások azonban nem tartoznak a cikk hatálya alá.

Alapszabályként mindig a AttributeConverter interfész és @ Converter megjegyzés, ha a JPA 2.1 vagy újabb verziót használjuk.

Szokás szerint az összes kódpélda elérhető a GitHub adattárunkban.

Java 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

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