Ivrig / lat lasting i dvale

Utholdenhetstopp

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

1. Introduksjon

Når du arbeider med en ORM, kan data henting / lasting klassifiseres i to typer: ivrig og lat.

I denne raske artikkelen skal vi påpeke forskjeller og vise at de kan brukes i dvalemodus.

2. Maven-avhengigheter

For å kunne bruke dvalemodus, la oss først definere hovedavhengigheten i vår pom.xml:

 org. dvalemodus dvalekjerne 5.2.2.Final 

Den siste versjonen av Hibernate finner du her.

3. Ivrig og lat lasting

Det første vi bør diskutere her er hva lat belastning og ivrig lasting er:

  • Ivrig lasting er et designmønster der datainitialisering skjer på stedet
  • Lazy Loading er et designmønster som brukes til å utsette initialiseringen av et objekt så lenge det er mulig

La oss se hvordan dette faktisk fungerer med noen eksempler:

De UserLazy klasse:

@Entity @Table (name = "USER") offentlig klasse UserLazy implementerer serierbar {@Id @GeneratedValue @Column (name = "USER_ID") privat Lang brukerId; @OneToMany (fetch = FetchType.LAZY, mappedBy = "bruker") privat Angi orderDetail = ny HashSet (); // standard setters og getters // overstyrer også lik og hashkode}

De OrderDetail klasse:

@Entity @Table (name = "USER_ORDER") offentlig klasse OrderDetail implementerer Serializable {@Id @GeneratedValue @Column (name = "ORDER_ID") private Long orderId; @ManyToOne (fetch = FetchType.LAZY) @JoinColumn (name = "USER_ID") privat UserLazy bruker; // standard setters og getters // overstyrer også lik og hashkode}

En Bruker kan ha flere Ordre detaljer. I ivrig lastestrategi, hvis vi laster inn Bruker data, vil den også laste opp alle bestillinger som er tilknyttet den, og lagre den i et minne.

Men når lat lasting er aktivert, hvis vi trekker opp a UserLazy, OrderDetail data vil ikke initialiseres og lastes inn i et minne før det blir ringt et eksplisitt anrop til det.

I neste avsnitt vil vi se hvordan eksemplet ovenfor er implementert i dvalemodus.

4. Laster konfigurasjon

I denne delen vil vi se på hvordan vi kan konfigurere hentestrategier i dvalemodus. Vi vil gjenbruke eksempler fra forrige avsnitt.

Lazy Loading kan bare aktiveres ved hjelp av følgende kommentarparameter:

hente = FetchType.LAZY

For å bruke ivrig henting brukes følgende parameter:

fetch = FetchType.EAGER

For å sette opp ivrig lasting har vi brukt UserLazy’S tvillingklasse kalt UserEager.

I neste avsnitt vil vi se på forskjellene mellom de to typene henting.

5. Forskjeller

Som vi nevnte, er hovedforskjellen mellom de to typene henting et øyeblikk når data blir lastet inn i et minne.

La oss ta en titt på dette eksemplet:

Liste brukere = sessionLazy.createQuery ("Fra UserLazy"). Liste (); UserLazy userLazyLoaded = users.get (3); returner (userLazyLoaded.getOrderDetail ());

Med den late initialiseringsmetoden, orderDetailSet vil først bli initialisert når det eksplisitt kalles ved hjelp av en getter eller en annen metode som vist i eksemplet ovenfor:

UserLazy userLazyLoaded = users.get (3);

Men med en ivrig tilnærming i UserEager den vil initialiseres umiddelbart i første linje i eksemplet ovenfor:

Liste bruker = sessionEager.createQuery ("Fra UserEager"). Liste ();

For lat lasting brukes et proxy-objekt, og et eget SQL-spørsmål blir utløst for å laste inn orderDetailSet .

Ideen om å deaktivere fullmakter eller lat lasting betraktes som dårlig praksis i dvalemodus. Det kan resultere i at mange data hentes fra en database og lagres i et minne, uavhengig av behovet for det.

Følgende metode kan brukes til å teste funksjonaliteten ovenfor:

Hibernate.isInitialized (orderDetailSet);

Nå er det viktig å se på spørsmålene som genereres i begge tilfeller:

ekte

Ovennevnte innstilling i fetching.hbm.xml viser SQL-spørringene som genereres. Hvis du ser på en konsollutgang, vil du kunne se genererte spørsmål.

For Lazy Loading spørringen som genereres for å laste inn Bruker data:

velg bruker0_.USER_ID som USER_ID1_0_, ... fra USER bruker0_

Imidlertid, i ivrig lasting, så vi en sammenføyning som ble laget med USER_ORDER:

velg orderdetai0_.USER_ID som USER_ID4_0_0_, orderdetai0_.ORDER_ID som ORDER_ID1_1_0_, orderdetai0_ ... fra USER_ORDER orderdetai0_ hvor orderdetai0_.USER_ID =?

Ovennevnte spørring genereres for alle Brukere, noe som resulterer i at mye mer minne blir brukt enn i den andre tilnærmingen.

6. Fordeler og ulemper

6.1. Lazy Loading

Fordeler:

  • Opprinnelig belastningstid mye mindre enn i den andre tilnærmingen
  • Mindre minneforbruk enn i den andre tilnærmingen

Ulemper:

  • Forsinket initialisering kan påvirke ytelsen i uønskede øyeblikk
  • I noen tilfeller må du håndtere objekter med lat initialisering med spesiell forsiktighet, ellers kan du ende opp med et unntak

6.2. Ivrig lasting:

Fordeler:

  • Ingen forsinket initialiseringsrelaterte ytelsespåvirkninger

Ulemper:

  • Lang starttid
  • Lasting av for mye unødvendige data kan påvirke ytelsen

7. Lazy Loading i dvale

Dvalemodus bruker tilnærming til lat belastning på enheter og foreninger ved å tilby en proxy-implementering av klasser.

Dvalemodus avlytter samtaler til en enhet ved å erstatte den med en fullmektig avledet fra en enhets klasse. I vårt eksempel, når en forespurt informasjon mangler, vil den lastes fra en database før kontroll blir avgitt til Bruker klasseimplementering.

Det skal også bemerkes at når foreningen er representert som en samlingsklasse (i eksemplene ovenfor er den representert som Angi orderDetailSet), så blir en innpakning opprettet og erstattet av en original samling.

For å vite mer om proxy-designmønster kan du referere her.

8. Konklusjon

I denne artikkelen viste vi eksempler på de to hovedtypene for henting som brukes i dvalemodus.

For ekspertise på avansert nivå, kan du se på den offisielle nettsiden til Hibernate. For å få koden diskutert i denne artikkelen, ta en titt på dette depotet.

Persistensbunn

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET