Hibernate One to Many Tutorial za bilješke
1. Uvod
Ovaj brzi vodič za hibernaciju provest će nas kroz primjer a jedan-prema-mnogima mapiranje pomoću JPA bilješki, alternative XML-u.
Također ćemo naučiti što su dvosmjerni odnosi, kako mogu stvoriti nedosljednosti i kako ideja vlasništva može pomoći.
2. Opis
Jednostavno rečeno,jedan prema mnogima preslikavanje znači da se jedan redak u tablici preslikava na više redaka u drugoj tablici.
Pogledajmo sljedeći dijagram odnosa entiteta da bismo vidjeli a jedan prema mnogima udruga:

U ovom ćemo primjeru implementirati sustav kolica u kojem imamo tablicu za svaku košaricu i drugu tablicu za svaku stavku. Jedna košarica može imati mnogo predmeta, pa ovdje imamo jedan-prema-mnogima mapiranje.
Način na koji ovo funkcionira na razini baze podataka je da imamo cart_id kao primarni ključ u kolica stol i također a cart_id kao strani ključ u predmeta.
Način na koji to radimo u kodu je s @OneToMany.
Mapirajmo Košarica razred do Predmeti objekt na način koji odražava odnos u bazi podataka:
košarica javne klase {// ... @OneToMany (mappedBy = "cart") private Set items; // ...}
Možemo dodati i referencu na Košarica u Predmeti koristeći @ManyToOne, čineći ovo dvosmjernim odnosom. Dvosmjerno znači da u mogućnosti smo pristupiti predmeta iz kolica, I također kolica iz predmeta.
The mapiranBy svojstvo je ono što koristimo kako bismo Hibernateu rekli koju varijablu koristimo za predstavljanje roditeljske klase u našoj podređenoj klasi.
Sljedeće tehnologije i knjižnice koriste se za razvoj uzorka Hibernate aplikacije koja se implementira jedan-prema-mnogima udruga:
- JDK 1.8 ili noviji
- Hibernate 5
- Maven 3 ili noviji
- H2 baza podataka
3. Postavljanje
3.1. Postavljanje baze podataka
Ispod je naša skripta baze podataka za Košarica i Predmeti stolovi. Ograničenje stranog ključa koristimo za jedan prema mnogima mapiranje:
STVORI TABLICU `Cart` (` cart_id` int (11) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`cart_id`)) MOTOR = InnoDB AUTO_INCREMENT = 5 ZADATAK KARSETET = utf8; STVORI TABELU `Predmeti` (` id` int (11) unsigned NOT NULL AUTO_INCREMENT, `cart_id` int (11) unsigned NOT NULL, PRIMARY KEY (` id`), KEY `cart_id` (` cart_id`), CONSTRAINT `items_ibfk_1 `STRANI KLJUČ (` cart_id`) LITERATURA `Košarica` (` cart_id`)) MOTOR = InnoDB AUTO_INCREMENT = 7 ZADATAK KARSETET = utf8;
Postavljanje baze podataka je spremno, pa prijeđimo na stvaranje primjera hibernacije.
3.2. Ovisnosti Mavena
Zatim ćemo našoj ovisnosti dodati Hibernate i H2 driver pom.xml datoteka. Ovisnost o hibernaciji koristi zapise JBoss i automatski se dodaje kao prijelazne ovisnosti:
- Hibernate verzija 5.2.7.Finalni
- Verzija H2 upravljačkog programa 1.4.197
Posjetite središnje spremište Maven za najnovije verzije hibernacije i ovisnosti o H2.
3.3. Konfiguracija hibernacije
Evo konfiguracije hibernacije:
org.h2.Driver jdbc: h2: mem: spring_hibernate_one_to_many sa org.hibernate.dialect.H2Dialect thread true
3.4. HibernateAnnotationUtil Razred
Uz HibernateAnnotationUtil klase, samo trebamo uputiti novu konfiguracijsku datoteku hibernacije:
privatna statička SessionFactory sessionFactory; private SessionFactory buildSessionFactory () {ServiceRegistry serviceRegistry = novi StandardServiceRegistryBuilder (). configure ("hibernate-annotation.cfg.xml"). build (); Metapodaci metapodaci = novi MetadataSources (serviceRegistry) .getMetadataBuilder (). Build (); SessionFactory sessionFactory = metadata.getSessionFactoryBuilder (). Build (); return sessionFactory; } javna SessionFactory getSessionFactory () {if (sessionFactory == null) sessionFactory = buildSessionFactory (); return sessionFactory; }
4. Modeli
Konfiguracije povezane s mapiranjem izvest će se pomoću JPA bilješki u klasama modela:
@Entity @Table (name = "CART") javna klasa Košarica {// ... @OneToMany (mappedBy = "cart") private Set items; // geteri i postavljači}
Imajte na umu da @OneToMany napomena se koristi za definiranje svojstva u Predmeti klasa koja će se koristiti za mapiranje mapiranBy varijabilna. Zbog toga imamo svojstvo pod nazivom „kolica”U Predmeti razred:
@Entity @Table (name = "ITEMS") stavke javne klase {// ... @ManyToOne @JoinColumn (name = "cart_id", nullable = false) košarica privatne košarice; javne stavke () {} // getters and setters}
Također je važno napomenuti da @ManyToOne bilješka je povezana s Košarica varijabla klase. @JoinColumn napomena upućuje na mapirani stupac.
5. Na djelu
U testnom programu stvaramo razred s a glavni() metoda za dobivanje Hibernate Session i spremanje objekata modela u bazu podataka koja implementira jedan-prema-mnogima udruga:
sessionFactory = HibernateAnnotationUtil.getSessionFactory (); session = sessionFactory.getCurrentSession (); System.out.println ("Sesija stvorena"); tx = session.beginTransaction (); session.save (kolica); session.save (stavka1); session.save (stavka2); tx.commit (); System.out.println ("Cartitem1, inozemni ključ Cartitem2, inozemni ključ Cartmany-to-one">6. The @ManyToOne BilješkaKao što smo vidjeli u odjeljku 2, možemo odrediti a mnogo-prema-jednom odnos pomoću @ManyToOne bilješka. A mnogo-prema-jednom mapiranje znači da su mnogi primjerci ovog entiteta mapirani u jedan primjerak drugog entiteta - mnogo predmeta u jednoj košarici.
The @ManyToOne anotacija nam omogućuje i stvaranje dvosmjernih odnosa. To ćemo detaljno pokriti u sljedećih nekoliko pododjeljaka.
6.1. Nedosljednosti i vlasništvo
Sad, ako Košarica referencirano Predmeti, ali Predmeti nije zauzvrat uputio Košarica, naš bi odnos bio jednosmjeran. Predmeti bi također imali prirodnu konzistenciju.
U našem slučaju, međutim, odnos je dvosmjeran, donoseći mogućnost nedosljednosti.
Zamislimo situaciju u kojoj programer želi dodati stavka1 do kolica i stavka2 do kolica2, ali griješi tako da reference između kolica2 i stavka2 postati nedosljedan:
Košarica1 = nova Košarica (); Košarica2 = nova Košarica (); Predmeti item1 = novi Predmeti (cart1); Artikli item2 = novi Artikli (košarica2); Postavi itemsSet = novi HashSet (); itemsSet.add (item1); itemsSet.add (item2); cart1.setItems (itemsSet); // pogrešno!
Kao što je prikazano gore, stavka2 reference kolica2, dok kolica2 ne upućuje stavka 2, a to je loše.
Kako Hibernate treba spasiti stavka2 u bazu podataka? Htjeti stavka2 referenca stranog ključa kolica1 ili kolica2?
Tu dvosmislenost rješavamo koristeći ideju vlasničke strane odnosa; reference koje pripadaju strani vlasnika imaju prednost i spremaju se u bazu podataka.
6.2. Predmeti kao Vlasnička strana
Kao što je navedeno u specifikaciji JPA u odjeljku 2.9, dobra je praksa za označavanje mnogo-prema-jednom strana kao strana posjedovanja.
Drugim riječima, Jatems bila bi vlasnička strana i Košarica inverzna strana, što smo upravo učinili ranije.
Pa kako smo to postigli?
Uključivanjem mapiranBy atribut u Košarica razreda, označavamo ga kao obrnutu stranu.
Istodobno također bilježimo Predmeti.kolica polje sa @ManyToOne, izrada Predmeti strana koja posjeduje.
Vraćajući se našem primjeru "nedosljednosti", Hibernate sada zna da stavka2Referenca je važnija i spasit će stavka2Referenca na bazu podataka.
Provjerimo rezultat:
item1 ID = 1, ID košarice s inozemnim ključem = 1 item2 ID = 2, ID košarice s inozemnim ključem = 2
Iako kolica reference stavka2 u našem isječku, stavka2Referenca na kolica2 se sprema u bazu podataka.
6.3. Košarica kao Vlasnička strana
Također je moguće označiti jedan-prema-mnogima strana kao strana koja posjeduje, i mnogo-prema-jednom strana kao inverzna strana.
Iako ovo nije preporučena praksa, krenimo i pokušajmo.
Isječak koda u nastavku prikazuje implementaciju jedan prema mnogima strana kao strana posjedovanja:
predmeti javne klaseOIO {// ... @ManyToOne @JoinColumn (name = "cart_id", insertable = false, Updatable = false) privatna košarica CartOIO; // ..} javna klasa CartOIO {// .. @OneToMany @JoinColumn (name = "cart_id") // moramo duplicirati fizičke podatke private Set stavke; // ..}
Primijetite kako smo uklonili mapiranBy element i postavite mnogo-prema-jednom @JoinColumn kao umetnuti i moguće ažurirati do lažno.
Ako pokrenemo isti kod, rezultat će biti suprotan:
item1 ID = 1, ID košarice s inozemnim ključem = 1 item2 ID = 2, ID košarice s inozemnim ključem = 1
Kao što je gore prikazano, sada stavka2 pripada kolica.
7. Zaključak
Vidjeli smo kako je lako implementirati jedan prema mnogima odnos s Hibernate ORM i H2 bazom podataka koristeći JPA bilješke.
Pored toga, naučili smo o dvosmjernim odnosima i kako primijeniti pojam posjedovanja strane.
Izvorni kod u ovom članku možete pronaći na GitHubu.