Prehľad identifikátorov v režime dlhodobého spánku / JPA

1. Úvod

Identifikátory v režime dlhodobého spánku predstavujú primárny kľúč entity. To znamená, že hodnoty sú jedinečné, aby mohli identifikovať konkrétnu entitu, neboli nulové a že sa nebudú meniť.

Režim dlhodobého spánku poskytuje niekoľko rôznych spôsobov definovania identifikátorov. V tomto článku preskúmame každú metódu mapovania ID entít pomocou knižnice.

2. Jednoduché identifikátory

Najjednoduchší spôsob definovania identifikátora je pomocou @Id anotácia.

Jednoduché ID sa mapujú pomocou @Id na jednu vlastnosť jedného z týchto typov: primitívne Java a primitívne obalové typy, Reťazec, dátum, BigDecimal, BigInteger.

Pozrime sa na krátky príklad definovania entity pomocou primárneho kľúča typu dlho:

@Entity public class Student {@Id private long studentId; // štandardný konštruktor, getre, setre}

3. Generované identifikátory

Ak chceme, aby sa nám hodnota primárneho kľúča generovala automaticky, môžeme pridať @GeneratedValue anotácia.

Môžete použiť 4 typy generácií: AUTO, IDENTITA, SEKVENCIA, TABUĽKA.

Ak nezadáme explicitne hodnotu, použije sa predvolene typ generovania AUTO.

3.1. AUTO Generácia

Ak používame predvolený typ generovania, poskytovateľ perzistencie určí hodnoty na základe typu atribútu primárneho kľúča. Tento typ môže byť numerický alebo UUID.

Pri číselných hodnotách je generovanie založené na generátore sekvencií alebo tabuliek, zatiaľ čo UUID hodnoty použijú UUIDGenerátor.

Pozrime sa na príklad mapovania primárneho kľúča entity pomocou stratégie generovania AUTO:

@Entity public class Student {@Id @GeneratedValue private long studentId; // ...}

V takom prípade budú hodnoty primárneho kľúča jedinečné na úrovni databázy.

Zaujímavou funkciou predstavenou v režime Hibernate 5 je UUIDGenerátor. Aby sme to mohli použiť, musíme iba deklarovať ID typu UUID s @GeneratedValue anotácia:

Kurz @Entity public class {@Id @GeneratedValue private UUID courseId; // ...}

Režim dlhodobého spánku vygeneruje ID v tvare „8dd5f315-9788-4d00-87bb-10eed9eff566“.

3.2. IDENTITA Generácia

Tento typ generácie sa spolieha na IdentityGenerator ktorá očakáva hodnoty vygenerované pomocou identita stĺpec v databáze, čo znamená, že sa zvyšujú automaticky.

Aby sme mohli použiť tento generačný typ, stačí nastaviť stratégia parameter:

@Entity public class Student {@Id @GeneratedValue (strategy = GenerationType.IDENTITY) private long studentId; // ...}

Je potrebné si uvedomiť, že generovanie IDENTITY zakazuje dávkové aktualizácie.

3.3. POSTUPNOSŤ Generácia

Ak chcete použiť ID založené na postupnosti, program Hibernate poskytuje SequenceStyleGenerator trieda.

Tento generátor používa sekvencie, ak sú podporované našou databázou, a prepína na generovanie tabuliek, ak nie sú.

Na prispôsobenie názvu sekvencie môžeme použiť znak @GenericGenerator anotácia s Stratégia SequenceStyleGenerator:

@Entity verejná trieda Používateľ {@Id @GeneratedValue (generátor = "sekvenčný generátor") @GenericGenerator (názov = "sekvenčný generátor", stratégia = "org.hibernate.id.enhanced.SequenceStyleGenerator", parametre = {@Parameter ( name = "sequence_name", value = "user_sequence"), @Parameter (name = "initial_value", value = "4"), @Parameter (name = "increment_size", value = "1")}) private long userId; // ...}

V tomto príklade sme tiež nastavili počiatočnú hodnotu pre sekvenciu, čo znamená, že generovanie primárneho kľúča začne na 4.

POSTUPNOSŤ je typ generácie odporúčaný v dokumentácii k režimu dlhodobého spánku.

Vygenerované hodnoty sú jedinečné pre každú sekvenciu. Ak nezadáte názov sekvencie, režim dlhodobého spánku použije rovnaký hibernate_sequence pre rôzne typy.

3.4. Generovanie tabuľky

The TableGenerator používa podkladovú databázovú tabuľku, ktorá obsahuje segmenty hodnôt generovania identifikátorov.

Poďme si prispôsobiť názov tabuľky pomocou @TableGenerator anotácia:

@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") súkromné ​​dlhé depId; // ...}

V tomto príklade vidíme, že ďalšie atribúty, ako napríklad pkColumnName a valueColumnName je možné aj prispôsobiť.

Nevýhodou tejto metódy je, že nemá dostatočný rozsah a môže negatívne ovplyvniť výkon.

Ak to zhrnieme, výsledkom týchto štyroch typov generovania budú podobné hodnoty, ktoré sa generujú, ale používajú rôzne databázové mechanizmy.

3.5. Vlastný generátor

Ak nechceme použiť niektorú z out-of-the-box stratégií, môžeme definovať náš vlastný generátor implementáciou IdentifikátorGenerátor rozhranie.

Vytvorme generátor, ktorý vytvorí identifikátory obsahujúce a String predpona a číslo:

verejná trieda MyGenerator implementuje IdentifierGenerator, konfigurovateľný {súkromná predpona reťazca; @ Verzia public Serializable generate (relácia SharedSessionContractImplementor, Object obj) hodí HibernateException {String query = String.format ("select% s from% s", session.getEntityPersister (obj.getClass (). GetName (), obj) .getIdentifierPropertyName ( ), obj.getClass (). getSimpleName ()); Stream ids = session.createQuery (dopyt) .stream (); Long max = ids.map (o -> o.replace (prefix + "-", "")) .mapToLong (Long :: parseLong) .max () .orElse (0L); návratová predpona + "-" + (max + 1); } @Override public void configure (typ typu, vlastnosti Vlastnosti, ServiceRegistry serviceRegistry) hodí MappingException {prefix = properties.getProperty ("predpona"); }}

V tomto príklade prepíšeme generovať () metóda z IdentifikátorGenerátor rozhranie a najskôr nájdite najvyššie číslo z existujúcich primárnych kľúčov formulára predpona-XX.

Potom k maximálnemu nájdenému počtu pripočítame 1 a pripojíme znak predpona vlastnosť na získanie novo vygenerovanej hodnoty id.

Naša trieda tiež implementuje Konfigurovateľné rozhranie, aby sme mohli nastaviť predpona hodnota majetku v Konfigurovať () metóda.

Ďalej pridajme tento vlastný generátor do entity. Pre to, môžeme použiť @GenericGenerator anotácia s a stratégia parameter, ktorý obsahuje celý názov triedy našej triedy generátora:

@Entity verejná trieda Produkt {@Id @GeneratedValue (generátor = "prod-generátor") @GenericGenerator (name = "prod-generátor", parametre = @Parameter (name = "predpona", hodnota = "prod"), stratégia = "com.baeldung.hibernate.pojo.generator.MyGenerator") private String prodId; // ...}

Všimnite si tiež, že sme nastavili parameter prefixu na „prod“.

Pozrime sa na rýchly test JUnit na lepšie pochopenie generovaných id hodnôt:

@Test public void whenSaveCustomGeneratedId_thenOk () {Product product = new Product (); session.save (produkt); Produkt product2 = nový produkt (); session.save (produkt2); assertThat (product2.getProdId ()). isEqualTo ("prod-2"); }

Tu bola prvá hodnota vygenerovaná pomocou predpony „prod“ „prod-1“, za ktorou nasledovala „prod-2“.

4. Zložené identifikátory

Okrem jednoduchých identifikátorov, ktoré sme doteraz videli, nám program Hibernate umožňuje definovať aj zložené identifikátory.

Zložené ID predstavuje trieda primárneho kľúča s jedným alebo viacerými pretrvávajúcimi atribútmi.

Trieda primárneho kľúča musí spĺňať niekoľko podmienok:

  • malo by to byť definované pomocou @EmbeddedId alebo @IdClass anotácie
  • mal by byť verejný, serializovateľný a mal by mať verejný konštruktor no-arg
  • malo by sa to realizovať rovná sa () a hashCode () metódy

Atribúty triedy môžu byť základné, zložené alebo ManyToOne, pričom sa vyhýbajú zbierkam a Jeden na jedného atribúty.

4.1. @EmbeddedId

Definovanie ID pomocou @EmbeddedId, najskôr potrebujeme triedu primárneho kľúča s poznámkami @Embeddable:

@Embeddable verejná trieda OrderEntryPK implementuje Serializable {private long orderId; súkromné ​​dlhé ID produktu; // štandardný konštruktor, getri, nastavovatelia // equals () a hashCode ()}

Ďalej môžeme pridať ID typu OrderEntryPK entite používajúcej @EmbeddedId:

@Entity verejná trieda OrderEntry {@EmbeddedId súkromná položka OrderEntryPK entryId; // ...}

Pozrime sa, ako môžeme pomocou tohto typu zloženého id nastaviť primárny kľúč pre entitu:

@Test public void whenSaveCompositeIdEntity_thenOk () {OrderEntryPK entryPK = new OrderEntryPK (); entryPK.setOrderId (1L); entryPK.setProductId (30L); OrderEntry entry = nový OrderEntry (); entry.setEntryId (entryPK); session.save (vstup); assertThat (entry.getEntryId (). getOrderId ()). isEqualTo (1L); }

Tu Vstupna objednavka objekt má OrderEntryPK primárne ID tvorené z dvoch atribútov: Číslo objednávky a identifikačné číslo produktu.

4.2. @IdClass

The @IdClass anotácia je podobná @EmbeddedId, okrem toho, že atribúty sú definované v hlavnej triede entít pomocou @Id pre každú jednu.

Trieda primárneho kľúča bude vyzerať rovnako ako predtým.

Prepíšme Vstupna objednavka príklad s @IdClass:

@Entity @IdClass (OrderEntryPK.class) verejná trieda OrderEntry {@Id private long orderId; @Id private long productId; // ...}

Potom môžeme nastaviť id hodnoty priamo na Vstupna objednavka objekt:

@Test public void whenSaveIdClassEntity_thenOk () {OrderEntry entry = new OrderEntry (); entry.setOrderId (1L); entry.setProductId (30L); session.save (vstup); assertThat (entry.getOrderId ()). isEqualTo (1L); }

Upozorňujeme, že pre oba typy zložených ID môže obsahovať aj trieda primárneho kľúča @ManyToOne atribúty.

Režim dlhodobého spánku tiež umožňuje definovať primárne kľúče, z ktorých sa skladá @ManyToOne združenia v kombinácii s @Id anotácia. V takom prípade by trieda entity mala tiež spĺňať podmienky triedy primárneho kľúča.

Nevýhodou tejto metódy je, že neexistuje oddelenie medzi objektom entity a identifikátorom.

5. Odvodené identifikátory

Odvodené identifikátory sa získavajú od asociácie subjektu pomocou @MapsId anotácia.

Najskôr vytvorme a Užívateľský profil subjekt, ktorý odvodzuje svoje identifikačné číslo od individuálneho združenia s Používateľ subjekt:

@Entity public class UserProfile {@Id private long profileId; @OneToOne @MapsId súkromný používateľ; // ...}

Ďalej overíme, či a Užívateľský profil inštancia má rovnaké ID ako je pridružená Používateľ inštancia:

@Test public void whenSaveDerivedIdEntity_thenOk () {User user = new User (); session.save (užívateľ); Profil UserProfile = nový UserProfile (); profile.setUser (užívateľ); session.save (profil); assertThat (profile.getProfileId ()). isEqualTo (user.getUserId ()); }

6. Záver

V tomto článku sme videli niekoľko spôsobov, ako môžeme definovať identifikátory v režime dlhodobého spánku.

Celý zdrojový kód príkladov nájdete na GitHub.


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