Željno / lijeno učitavanje u hibernaciji
Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:
>> PROVJERITE TEČAJ1. Uvod
Kada radite s ORM-om, dohvaćanje / učitavanje podataka može se klasificirati u dvije vrste: željno i lijeno.
U ovom kratkom članku ukazat ćemo na razlike i pokazati kako se one mogu koristiti u hibernaciji.
2. Ovisnosti Mavena
Da bismo koristili hibernaciju, definirajmo prvo glavnu ovisnost u našem pom.xml:
org.hibernate hibernate-core 5.2.2.Final
Najnoviju verziju hibernacije možete pronaći ovdje.
3. Željno i lijeno učitavanje
Prvo o čemu bismo ovdje trebali razgovarati je što su lijeno i željno utovar:
- Željno učitavanje je obrazac dizajna u kojem se inicijalizacija podataka događa na licu mjesta
- Lijeno učitavanje je obrazac dizajna koji se koristi za odgađanje inicijalizacije objekta sve dok je to moguće
Pogledajmo kako ovo zapravo funkcionira na nekoliko primjera:
The UserLazy razred:
@Entity @Table (name = "USER") javna klasa UserLazy implementira Serializable {@Id @GeneratedValue @Column (name = "USER_ID") private Long userId; @OneToMany (fetch = FetchType.LAZY, mappedBy = "user") private Set orderDetail = new HashSet (); // standardni postavljači i getteri // također nadjačavaju equals i hashcode}
The Pojedinosti narudžbe razred:
@Entity @Table (name = "USER_ORDER") javna klasa OrderDetail implementira Serializable {@Id @GeneratedValue @Column (name = "ORDER_ID") private Long orderId; @ManyToOne (fetch = FetchType.LAZY) @JoinColumn (name = "USER_ID") privatni UserLazy korisnik; // standardni postavljači i getteri // također nadjačavaju equals i hashcode}
Jedan Korisnik može imati više Detalji narudžbe. U željnoj strategiji učitavanja, ako učitamo Korisnik podataka, također će učitati sve naloge povezane s njom i pohranit će ih u memoriju.
Ali, kada je omogućeno lijeno učitavanje, ako povučemo a UserLazy, Pojedinosti narudžbe podaci se neće inicijalizirati i učitati u memoriju dok im se ne uputi izričit poziv.
U sljedećem odjeljku vidjet ćemo kako se gornji primjer provodi u hibernaciji.
4. Učitavanje konfiguracije
U ovom ćemo odjeljku pogledati kako možemo konfigurirati strategije dohvaćanja u hibernaciji. Ponovno ćemo upotrijebiti primjere iz prethodnog odjeljka.
Lijeno učitavanje može se jednostavno omogućiti pomoću sljedećeg parametra bilješke:
dohvat = FetchType.LAZNO
Za upotrebu nestrpljivog dohvaćanja koristi se sljedeći parametar:
dohvat = FetchType.EAGER
Za postavljanje željnog učitavanja koristili smo UserLazy'S twin class zove UserEager.
U sljedećem ćemo dijelu pogledati razlike između dvije vrste dohvaćanja.
5. Razlike
Kao što smo spomenuli, glavna razlika između dvije vrste dohvaćanja je trenutak kada se podaci učitavaju u memoriju.
Pogledajmo ovaj primjer:
Popis korisnika = sessionLazy.createQuery ("From UserLazy"). List (); UserLazy userLazyLoaded = users.get (3); return (userLazyLoaded.getOrderDetail ());
Uz lijeni pristup inicijalizaciji, orderDetailSet će se inicijalizirati samo kad je izričito pozvan pomoću getera ili neke druge metode kao što je prikazano u gornjem primjeru:
UserLazy userLazyLoaded = users.get (3);
Ali sa željnim pristupom u UserEager bit će inicijaliziran odmah u prvom retku gornjeg primjera:
Popis korisnika = sessionEager.createQuery ("Iz UserEager"). List ();
Za lijeno učitavanje koristi se objekt proxy i pokreće se zasebni SQL upit za učitavanje orderDetailSet .
Ideja o onemogućavanju proxyja ili lijenom učitavanju smatra se lošom praksom u hibernaciji. To može rezultirati velikim brojem podataka koji se preuzimaju iz baze podataka i pohranjuju u memoriju, bez obzira na potrebu za njima.
Sljedeća metoda može se koristiti za testiranje gore navedene funkcionalnosti:
Hibernate.isInitialized (orderDetailSet);
Sada je važno pogledati upite koji se generiraju u oba slučaja:
pravi
Gornja postavka u dohvaćanje.hbm.xml prikazuje generirane SQL upite. Ako pogledate izlaz konzole, moći ćete vidjeti generirane upite.
Za lijeno učitavanje upita koji se generira za učitavanje Korisnik podaci:
odaberite user0_.USER_ID kao USER_ID1_0_, ... od USER user0_
Međutim, u nestrpljivom utovaru, vidjeli smo kako se spaja spoj USER_ORDER:
odaberite orderdetai0_.USER_ID kao USER_ID4_0_0_, orderdetai0_.ORDER_ID kao ORDER_ID1_1_0_, orderdetai0_ ... iz USER_ORDER orderdetai0_ gdje orderdetai0_.USER_ID =?
Gornji upit generira se za sve Korisnici, što rezultira korištenjem mnogo više memorije nego u drugom pristupu.
6. Prednosti i nedostaci
6.1. Lijeno učitavanje
Prednosti:
- Početno vrijeme opterećenja mnogo je manje nego kod drugog pristupa
- Manja potrošnja memorije nego u drugom pristupu
Mane:
- Odgođena inicijalizacija može utjecati na performanse tijekom neželjenih trenutaka
- U nekim slučajevima trebate postupati s lijeno inicijaliziranim objektima s posebnom pažnjom ili biste u konačnici mogli izuzeti
6.2. Željno učitavanje:
Prednosti:
- Nema utjecaja izvedbe na odgođenu inicijalizaciju
Mane:
- Dugo početno vrijeme utovara
- Učitavanje previše nepotrebnih podataka može utjecati na performanse
7. Lijeno utovar u hibernaciji
Hibernate primjenjuje pristup lijenog učitavanja na entitete i udruge pružajući proxy implementaciju razreda.
Hibernate presreće pozive entitetu zamjenjujući ga proxyjem izvedenim iz klase entiteta. U našem primjeru, kada tražena informacija nedostaje, ona će se učitati iz baze podataka prije nego što se kontrola ustupi Korisnik provedba razreda.
Također treba napomenuti da je udruga predstavljena kao klasa kolekcije (u gornjim primjerima predstavljena je kao Postavi orderDetailSet), tada se stvara omot i zamjenjuje originalna kolekcija.
Da biste saznali više o uzorku dizajna proxyja, možete se obratiti ovdje.
8. Zaključak
U ovom smo članku prikazali primjere dvije glavne vrste dohvaćanja koje se koriste u hibernaciji.
Za naprednu stručnost možete pogledati službenu web stranicu Hibernate. Da biste dobili kod o kojem se govori u ovom članku, pogledajte ovo spremište.
Dno postojanosti