A hibernált / JPA azonosítók áttekintése
1. Bemutatkozás
A hibernált állapotban lévő azonosítók jelentik az entitás elsődleges kulcsát. Ez azt jelenti, hogy az értékek egyediek, így azonosítani tudnak egy adott entitást, nem nullák és nem módosulnak.
A hibernálás néhány különböző módszert kínál az azonosítók meghatározására. Ebben a cikkben áttekintjük az entitásazonosítók leképezésének minden módszerét a könyvtár segítségével.
2. Egyszerű azonosítók
Az azonosító meghatározásának legegyszerűbb módja a @Id annotáció.
Az egyszerű azonosítókat a segítségével térképezzük fel @Id az egyik ilyen tulajdonság egyetlen tulajdonságára: Java primitív és primitív burkoló típusok, Karakterlánc, dátum, BigDecimal, BigInteger.
Lássunk egy gyors példát egy entitás definiálására egy elsődleges típusú kulccsal hosszú:
@Entity public class Student {@Id private long studentId; // szabványos kivitelező, mérőeszközök, beállítók}
3. Generált azonosítók
Ha azt akarjuk, hogy az elsődleges kulcsérték automatikusan generálódjon számunkra, hozzáadhatjuk a @GeneratedValue annotáció.
Ez 4 generációs típust használhat: AUTO, IDENTITY, SEQUENCE, TABLE.
Ha nem adunk meg kifejezetten értéket, akkor a generációs típus alapértelmezés szerint AUTO.
3.1. AUTO Generáció
Ha az alapértelmezett generációs típust használjuk, akkor a perzisztenciaszolgáltató az elsődleges kulcsattribútum típusa alapján határozza meg az értékeket. Ez a típus lehet numerikus vagy UUID.
Numerikus értékek esetén a generálás szekvencia vagy tábla generátoron alapszik, míg UUID értékek a UUIDGenerator.
Lássunk egy példát egy entitás elsődleges kulcsának leképezésére az AUTO generációs stratégia használatával:
@Entity public class Student {@Id @GeneratedValue private long studentId; // ...}
Ebben az esetben az elsődleges kulcsértékek adatbázis-szinten egyediek lesznek.
A Hibernate 5 érdekes funkciója a UUIDGenerator. Ennek használatához csak egy típusazonosítót kell deklarálnunk UUID val vel @GeneratedValue kommentár:
@Entity public class Course {@Id @GeneratedValue private UUID courseId; // ...}
A hibernálás a „8dd5f315-9788-4d00-87bb-10eed9eff566” formátumú azonosítót generálja.
3.2. IDENTITÁS Generáció
Ez a fajta generáció a IdentityGenerator amely egy an által generált értékeket vár identitás oszlopot az adatbázisban, vagyis automatikusan növekszik.
Ennek a generációs típusnak a használatához csak a stratégia paraméter:
@Entity public class Student {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) private long studentId; // ...}
Egy dolgot érdemes megjegyezni, hogy az IDENTITY generálás letiltja a kötegelt frissítéseket.
3.3. SORREND Generáció
A szekvencia alapú azonosító használatához a Hibernate megadja a SequenceStyleGenerator osztály.
Ez a generátor szekvenciákat használ, ha az adatbázisunk támogatja őket, és ha nem, táblák generálására vált.
A sorozat nevének testreszabásához használhatjuk a @GenericGenerator annotáció azzal SequenceStyleGenerator stratégia:
@Entity public class Felhasználó {@Id @GeneratedValue (generátor = "szekvencia-generátor") @ GeneratorGenerator (név = "szekvencia-generátor", stratégia = "org.hibernate.id.enhanced.SequenceStyleGenerator", paraméterek = {@Parameter ( név = "sorozat_név", érték = "felhasználó_szekvencia"), @Paraméter (név = "kezdeti_érték", érték = "4"), @Paraméter (név = "növekmény_méret", érték = "1")}) privát hosszú userId; // ...}
Ebben a példában a kezdeti értéket is beállítottuk a sorozatnak, ami azt jelenti, hogy az elsődleges kulcs előállítása 4-nél kezdődik.
SORREND a hibernált dokumentáció által ajánlott generációs típus.
A generált értékek szekvenciánként egyediek. Ha nem ad meg sorrendnevet, akkor a Hibernate újra felhasználja hibernált_ következmény különböző típusokhoz.
3.4. TÁBLÁZAT Generálás
A TableGenerator egy mögöttes adatbázis-táblázatot használ, amely az azonosító létrehozásának értékeit tartalmazza.
Testreszabjuk a tábla nevét a @TableGenerator kommentár:
@Entity public class Department {@Id @GeneratedValue (strategy = GenerationType.TABLE, generator = "table-generator") @TableGenerator (name = "table-generator", table = "dep_ids", pkColumnName = "seq_id", valueColumnName = "seq_value") private long depId; // ...}
Ebben a példában láthatjuk, hogy más attribútumok, például a pkColumnName és valueColumnName testreszabható is.
A módszer hátránya, hogy nem méretezhető jól, és negatívan befolyásolhatja a teljesítményt.
Összegezve: ez a négy generációs típus hasonló értékeket generál, de különböző adatbázis-mechanizmusokat használ.
3.5. Custom Generator
Ha nem akarunk a dobozon kívüli stratégiák egyikét sem használni, meghatározhatjuk egyéni generátorunkat a IdentifierGenerator felület.
Hozzunk létre egy generátort, amely a-t tartalmazó azonosítókat épít Húr előtag és szám:
public class A MyGenerator megvalósítja az IdentifierGenerator, konfigurálható {private String előtagot; A @Orride nyilvános Serializálható generálás (SharedSessionContractImplementor session, Object obj) eldobja a HibernateException {String query = String.format ("% s kiválasztása% s közül", session.getEntityPersister (obj.getClass (). GetName (), obj) .getIdentifierPropertyName ( ), obj.getClass (). getSimpleName ()); Patak azonosítói = session.createQuery (query) .stream (); Hosszú max = ids.map (o -> o.csere (előtag + "-", "")) .mapToLong (Long :: parseLong) .max () .orElse (0L); visszatérő előtag + "-" + (max + 1); } @Orride public void configure (Type type, Properties properties, ServiceRegistry serviceRegistry) dobja a MappingException {prefix = properties.getProperty ("előtag"); }}
Ebben a példában felülírjuk a generál() módszer a IdentifierGenerator felület és először keresse meg a legnagyobb számot az űrlap meglévő elsődleges kulcsai közül előtag-XX.
Ezután hozzáadunk 1-et a maximálisan talált számhoz, és hozzáfűzzük a előtag tulajdonság az újonnan létrehozott id érték megszerzéséhez.
Osztályunk is megvalósítja a Konfigurálható felületet, hogy beállítsuk a előtag tulajdonság értéke a Beállítás() módszer.
Ezután adjuk hozzá ezt az egyéni generátort egy entitáshoz. Ezért, használhatjuk a @GenericGenerator annotáció a-val stratégia paraméter, amely a generátor osztályunk teljes osztálynevét tartalmazza:
@Entity public class Termék {@Id @GeneratedValue (generátor = "prod-generátor") @GenericGenerator (név = "prod-generátor", paraméterek = @Parameter (név = "előtag", érték = "prod"), stratégia = "com.baeldung.hibernate.pojo.generator.MyGenerator") private String prodId; // ...}
Ezenkívül vegye figyelembe, hogy az előtag paramétert „prod” -ra állítottuk.
Lássunk egy gyors JUnit tesztet a létrehozott id értékek tisztább megértése érdekében:
@Test public void whenSaveCustomGeneratedId_thenOk () {Product product = new Product (); session.save (termék); Termék termék2 = új termék (); session.save (termék2); assertThat (termék2.getProdId ()). isEqualTo ("prod-2"); }
Itt a „prod” előtaggal előállított első érték a „prod-1” volt, amelyet a „prod-2” követett.
4. Kompozit azonosítók
Az eddig látott egyszerű azonosítók mellett a hibernálás lehetővé teszi számunkra az összetett azonosítók meghatározását is.
Az összetett azonosítót egy elsődleges kulcsosztály képviseli, egy vagy több állandó attribútummal.
Az elsődleges kulcsosztálynak több feltételt kell teljesítenie:
- segítségével kell meghatározni @EmbeddedId vagy @IdClass annotációk
- legyen nyilvános, sorosítható és legyen nyilvános no-arg konstruktora
- meg kellene valósítania egyenlő () és hash kód() mód
Az osztály attribútumai lehetnek alapszintűek, összetettek vagy ManyToOne, elkerülve a gyűjteményeket és 1-1 attribútumokat.
4.1. @EmbeddedId
Azonosító definiálása a @EmbeddedId, először egy elsődleges kulcsosztályra van szükségünk, amelyhez meg kell jegyezni @ Beágyazható:
@Embeddable public class A OrderEntryPK megvalósítja a Serializable {private long orderId; magán hosszú termékId; // szabványos konstruktor, getterek, beállítók // egyenlő () és hashCode ()}
Ezután hozzáadhatunk egy típusú azonosítót OrderEntryPK a @ használatávalEmbeddedId:
@Entity public class OrderEntry {@EmbeddedId private OrderEntryPK entryId; // ...}
Nézzük meg, hogyan használhatjuk az ilyen típusú összetett azonosítót az entitás elsődleges kulcsának beállításához:
@Test public void whenSaveCompositeIdEntity_thenOk () {OrderEntryPK entryPK = new OrderEntryPK (); entryPK.setOrderId (1L); entryPK.setProductId (30L); OrderEntry bejegyzés = new OrderEntry (); entry.setEntryId (entryPK); session.save (bejegyzés); assertThat (entry.getEntryId (). getOrderId ()). isEqualTo (1L); }
Itt a OrderEntry objektumnak van egy OrderEntryPK két tulajdonságból álló elsődleges azonosító: Rendelés azonosító és termék azonosító.
4.2. @IdClass
A @IdClass annotáció hasonló a @EmbeddedId, kivéve, hogy az attribútumokat a fő entitásosztályban a @Id mindegyikre.
Az elsődleges kulcs osztály ugyanaz lesz, mint korábban.
Írjuk át a OrderEntry példa egy @IdClass:
@Entity @IdClass (OrderEntryPK.class) public class OrderEntry {@Id private long orderId; @Id private long productId; // ...}
Ezután beállíthatjuk az id értékeket közvetlenül a OrderEntry tárgy:
@Test public void whenSaveIdClassEntity_thenOk () {OrderEntry entry = new OrderEntry (); entry.setOrderId (1L); entry.setProductId (30L); session.save (bejegyzés); assertThat (entry.getOrderId ()). isEqualTo (1L); }
Vegye figyelembe, hogy mindkét típusú összetett azonosító esetében az elsődleges kulcsosztály is tartalmazhat @ManyToOne attribútumokat.
A hibernálás lehetővé teszi az elsődleges kulcsok definiálását is @ManyToOne társulásokkal kombinálva @Id annotáció. Ebben az esetben az entitásosztálynak meg kell felelnie az elsődleges kulcs osztály feltételeinek is.
Ennek a módszernek az a hátránya, hogy nincs különbség az entitás objektum és az azonosító között.
5. Származtatott azonosítók
A származtatott azonosítókat egy entitás társításától kapják meg a @MapsId annotáció.
Először hozzunk létre egy Felhasználói profil entitás, amely azonosítóját a Felhasználó entitás:
@Entity public class UserProfile {@Id private long profileId; @OneToOne @MapsId magánfelhasználó felhasználó; // ...}
Ezután ellenőrizzük, hogy a Felhasználói profil példány azonos azonosítóval rendelkezik, mint a társított Felhasználó példa:
@Test public void whenSaveDerivedIdEntity_thenOk () {Felhasználó felhasználó = új Felhasználó (); session.save (felhasználó); UserProfile profil = new UserProfile (); profile.setUser (felhasználó); session.save (profil); assertThat (profile.getProfileId ()). isEqualTo (user.getUserId ()); }
6. Következtetés
Ebben a cikkben többféle módon láthattuk az azonosítókat a hibernált állapotban.
A példák teljes forráskódja megtalálható a GitHub oldalon.