Željno / lijeno učitavanje u hibernaciji

Vrh postojanosti

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

1. 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

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ