Proxy i dvaleindlæsningsmetode ()

1. Oversigt

I denne vejledning ser vi, hvad en proxy er i sammenhæng med dvale belastning() metode.

For læsere, der ikke er i dvale, overvej først at blive fortrolig med det grundlæggende.

2. En kort introduktion til fuldmagter og belastning() Metode

Per definition er en fuldmagt "en funktion, der er autoriseret til at fungere som stedfortræder eller erstatning for en anden".

Dette gælder for dvale, når vi ringer Session.load () at skabe det, der kaldes en uinitialiseret proxy af vores ønskede enhedsklasse.

Kort sagt, dvale underklasser vores enhedsklasse ved hjælp af CGLib bibliotek. Andet end @Id metode delegerer proxyimplementeringen alle andre egenskabsmetoder til dvale-sessionen for at udfylde forekomsten, noget som:

offentlig klasse HibernateProxy udvider MyEntity {privat MyEntity-mål; offentlig String getFirstName () {if (target == null) {target = readFromDatabase (); } returner target.getFirstName (); }}

Denne underklasse vil være den, der skal returneres i stedet for at spørge direkte til databasen.

Når en af ​​enhedsmetoderne kaldes, indlæses enheden og bliver på det tidspunkt en initialiseret proxy.

3. Proxyer og dovne Indlæser

3.1. En enkelt enhed

Lad os tænke over Medarbejder som en enhed. Til at begynde med antager vi, at det ikke har nogen relation til andre tabeller.

Hvis vi bruger Session.load () at instantiere en Medarbejder:

Medarbejder albert = session.load (Medarbejderklasse, ny Lang (1));

Derefter opretter dvaletilstand en uinitialiseret proxy for Medarbejder. Det vil indeholde det ID, som vi gav det, men ellers har det ingen andre værdier, fordi vi endnu ikke har ramt databasen.

Men når vi først kalder en metode på Albert:

String firstName = albert.getFirstName ();

Derefter vil dvaletilstand spørge medarbejder databasetabel for en enhed med en primær nøgle på 1, der udfylder Albert med hans egenskaber fra den tilsvarende række.

Hvis det ikke lykkes at finde en række, kaster dvale en ObjectNotFoundException.

3.2. En-til-mange forhold

Lad os nu oprette en Selskab enhed også, hvor en Selskab har mange Medarbejdere:

offentlig klasseselskab {privat strengnavn; private Set-medarbejdere; }

Hvis vi denne gang bruger Session.load () om virksomheden:

Virksomhedsbizco = session.load (Company.class, ny Long (1)); Strengnavn = bizco.getName ();

Derefter er virksomhedens ejendomme befolket som før, undtagen medarbejdernes sæt er bare lidt anderledes.

Se, vi forespurgte kun om virksomhedsrækken, men proxyen lader medarbejderen være alene, indtil vi ringer getMedarbejdere afhængigt af hentningsstrategien.

3.3. Mange-til-en-forhold

Sagen er ens i den modsatte retning:

offentlig klassemedarbejder {privat streng fornavn; privat virksomheds arbejdsplads; }

Hvis vi bruger belastning() igen:

Medarbejder bob = session.load (Medarbejder.klasse, ny Lang (2)); String firstName = bob.getFirstName ();

bob vil nu blive initialiseret og faktisk arbejdsplads vil nu blive indstillet til at være en ikke-initialiseret proxy afhængigt af hentningsstrategien.

4. Lazy-ish Loading

Nu, belastning() giver os ikke altid en uinitialiseret proxy. Faktisk er det Session java doc minder os om (fremhævelse tilføjet):

Denne metode magt returnere en proxied instans, der initialiseres on-demand, når der er adgang til en ikke-identificeringsmetode.

Et simpelt eksempel på, hvornår dette kan ske, er med batchstørrelse.

Lad os sige, at vi bruger @BatchSize på vores Medarbejder enhed:

@Entity @BatchSize (størrelse = 5) klasse Medarbejder {// ...}

Og denne gang har vi tre medarbejdere:

Medarbejdercatherine = session.load (Medarbejderklasse, ny Lang (3)); Medarbejderdarrell = session.load (Medarbejderklasse, ny Lang (4)); Medarbejderemma = session.load (Medarbejderklasse, ny Lang (5));

Hvis vi ringer getFirstName Catherine:

String cathy = catherine.getFirstName ();

Derefter kan Hibernate faktisk beslutte at indlæse alle tre medarbejdere på én gang og gøre alle tre til initialiserede fuldmagter.

Og så når vi kalder på darrell'S fornavn:

String darrell = darrell.getFirstName ();

Derefter Dvaletilstand rammer slet ikke databasen.

5. Ivrig indlæsning

5.1. Ved brug af få()

Vi kan også omgå fuldmagter fuldstændigt og bede dvale om at indlæse den rigtige ting ved hjælp af Session.get ():

Medarbejder finnigan = session.get (Medarbejderklasse, ny Lang (6));

Dette kalder databasen med det samme i stedet for at returnere en proxy.

Og faktisk i stedet for en ObjectNotFoundException, det vender tilbage nul hvis finnigan eksisterer ikke.

5.2. Implikationer for ydeevne

Mens få() er praktisk, belastning() kan være lettere i databasen.

Lad os for eksempel sige gerald skal arbejde for et nyt firma:

Medarbejder gerald = session.get (Medarbejder.klasse, ny Lang (7)); Company worldco = (Company) session.load (Company.class, new Long (2)); medarbejder.setCompany (worldco); session.save (medarbejder);

Da vi ved, at vi kun vil ændre medarbejder registrere i denne situation, ringer belastning() til Selskab er fornuftigt.

Hvis vi ringede få()Selskab, så ville vi have indlæst alle dens data unødvendigt fra databasen.

6. Konklusion

I denne artikel lærte vi kort hvordan Dvale fuldmagter fungerer, og hvordan dette påvirker belastning metode med enheder og deres relationer.

Vi kiggede også hurtigt på hvordan belastning() adskiller sig fra få().

Som sædvanlig er den fulde kildekode, der ledsager vejledningen, tilgængelig på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found