Ivrig / doven lastning i dvale

Udholdenhedstop

Jeg har lige annonceret det nye Lær foråret kursus med fokus på det grundlæggende i Spring 5 og Spring Boot 2:

>> KONTROLLER KURSEN

1. Introduktion

Når du arbejder med en ORM, kan data hentning / indlæsning klassificeres i to typer: ivrig og doven.

I denne hurtige artikel vil vi påpege forskelle og vise, at de kan bruges i dvale.

2. Maven-afhængigheder

Lad os først definere den vigtigste afhængighed i vores for at bruge dvale pom.xml:

 org. dvale-dvale-kerne 5.2.2.Final 

Den seneste version af dvale kan findes her.

3. Ivrig og doven lastning

Den første ting, vi skal diskutere her, er, hvad doven belastning og ivrig lastning er:

  • Ivrig indlæsning er et designmønster, hvor initialisering af data sker på stedet
  • Lazy Loading er et designmønster, der bruges til at udsætte initialisering af et objekt, så længe det er muligt

Lad os se, hvordan dette rent faktisk fungerer med nogle eksempler:

Det UserLazy klasse:

@Entity @Table (name = "USER") offentlig klasse UserLazy implementerer Serialiserbar {@Id @GeneratedValue @Column (name = "USER_ID") privat Lang brugerId; @OneToMany (fetch = FetchType.LAZY, mappedBy = "bruger") privat Indstil orderDetail = ny HashSet (); // standard settere og getters // tilsidesætter også lig og hashcode}

Det OrderDetail klasse:

@Entity @Table (name = "USER_ORDER") offentlig klasse OrderDetail implementerer Serializable {@Id @GeneratedValue @Column (name = "ORDER_ID") privat Lang orderId; @ManyToOne (fetch = FetchType.LAZY) @JoinColumn (name = "USER_ID") privat UserLazy bruger; // standard setters og getters // tilsidesætter også lig og hashcode}

En Bruger kan have flere Ordre detaljer. I ivrig lastningsstrategi, hvis vi indlæser Bruger data, vil det også indlæse alle ordrer, der er knyttet til det, og gemme det i en hukommelse.

Men når doven belastning er aktiveret, hvis vi trækker op a UserLazy, OrderDetail data initialiseres ikke og indlæses i en hukommelse, før der foretages et eksplicit opkald til det.

I det næste afsnit vil vi se, hvordan ovenstående eksempel implementeres i dvale.

4. Indlæsningskonfiguration

I dette afsnit vil vi se på, hvordan vi kan konfigurere hentestrategier i dvale. Vi genbruger eksempler fra det foregående afsnit.

Lazy Loading kan simpelthen aktiveres ved hjælp af følgende annoteringsparameter:

hente = FetchType.LAZY

For at bruge ivrig hentning bruges følgende parameter:

hente = FetchType.EAGER

Til opsætning af ivrig indlæsning har vi brugt UserLazy'S tvillingeklasse kaldet UserEager.

I det næste afsnit vil vi se på forskellene mellem de to typer hentning.

5. Forskelle

Som vi nævnte, er den største forskel mellem de to typer hentning et øjeblik, hvor data indlæses i en hukommelse.

Lad os se på dette eksempel:

Liste brugere = sessionLazy.createQuery ("Fra UserLazy"). Liste (); UserLazy userLazyLoaded = brugere.get (3); returnere (userLazyLoaded.getOrderDetail ());

Med den dovne initialiseringsmetode, orderDetailSet initialiseres kun, når det udtrykkeligt kaldes ved hjælp af en getter eller en anden metode som vist i eksemplet ovenfor:

UserLazy userLazyLoaded = brugere.get (3);

Men med en ivrig tilgang ind UserEager det initialiseres straks i første linje i eksemplet ovenfor:

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

Til doven indlæsning bruges et proxyobjekt, og en separat SQL-forespørgsel affyres for at indlæse orderDetailSet .

Ideen om at deaktivere fuldmagter eller doven indlæsning betragtes som en dårlig praksis i dvale. Det kan resultere i, at mange data hentes fra en database og lagres i en hukommelse, uanset behovet for det.

Følgende metode kan bruges til at teste ovenstående funktionalitet:

Hibernate.isInitialized (orderDetailSet);

Nu er det vigtigt at se på de forespørgsler, der genereres i begge tilfælde:

rigtigt

Ovenstående indstilling i henter.hbm.xml viser de SQL-forespørgsler, der genereres. Hvis du ser på et konsoloutput, vil du kunne se genererede forespørgsler.

For Lazy Loading den forespørgsel, der genereres for at indlæse Bruger data:

vælg bruger0_.USER_ID som USER_ID1_0_, ... fra USER bruger0_

Under ivrig lastning så vi dog en sammenføjning blev lavet med USER_ORDER:

vælg 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 =?

Ovenstående forespørgsel genereres for alle Brugere, hvilket resulterer i, at der bruges meget mere hukommelse end i den anden tilgang.

6. Fordele og ulemper

6.1. Lazy Loading

Fordele:

  • Indledende belastningstid meget mindre end i den anden tilgang
  • Mindre hukommelsesforbrug end i den anden tilgang

Ulemper:

  • Forsinket initialisering kan påvirke ydeevnen under uønskede øjeblikke
  • I nogle tilfælde er du nødt til at håndtere doven-initialiserede genstande med særlig omhu, eller du kan ende med en undtagelse

6.2. Ivrig indlæsning:

Fordele:

  • Ingen forsinkede initialiseringsrelaterede ydeevneeffekter

Ulemper:

  • Lang indlæsningstid
  • Indlæsning af for mange unødvendige data kan påvirke ydeevnen

7. Lazy Loading i dvale

Dvaletilstand anvender tilgang til doven indlæsning på enheder og foreninger ved at give en proxyimplementering af klasser.

Dvale aflytter opkald til en enhed ved at erstatte den med en proxy afledt af en enheds klasse. I vores eksempel, når en anmodet information mangler, indlæses den fra en database, før kontrol overgives til Bruger klasseimplementering.

Det skal også bemærkes, at når foreningen er repræsenteret som en samlingsklasse (i eksemplerne ovenfor er den repræsenteret som Indstil orderDetailSet), så oprettes en indpakning og erstattes af en original samling.

For at vide mere om proxy design mønster kan du henvise her.

8. Konklusion

I denne artikel viste vi eksempler på de to hovedtyper af hentning, der bruges i dvale.

For ekspertise på avanceret niveau kan du se på den officielle hjemmeside for dvale. For at få koden diskuteret i denne artikel skal du kigge på dette lager.

Persistens bund

Jeg har lige annonceret det nye Lær foråret kursus med fokus på det grundlæggende i Spring 5 og Spring Boot 2:

>> KONTROLLER KURSEN