Hjelp meg å forstå hvor jeg skal bruke en vanlig JOIN og hvor jeg skal bruke en JOIN FETCH.
Hvis vi for eksempel har disse to spørringene
FROM Employee emp
JOIN emp.department dep
og
FROM Employee emp
JOIN FETCH emp.department dep
Er det noen forskjell på dem? Hvis ja, hvilken skal jeg bruke når?
I disse to spørringene bruker du JOIN til å søke etter alle ansatte som har minst én avdeling tilknyttet.
Forskjellen er imidlertid at i den første spørringen returnerer du bare Employes for Hibernate. I den andre spørringen returnerer du Employes og alle tilknyttede avdelinger.
Så hvis du bruker den andre spørringen, trenger du ikke å gjøre en ny spørring i databasen for å se avdelingene til hver ansatt.
Du kan bruke den andre spørringen når du er sikker på at du trenger avdelingen til hver ansatt. Hvis du ikke trenger avdelingen, kan du bruke den første spørringen.
Jeg anbefaler at du leser denne lenken hvis du trenger å bruke noen WHERE-betingelser (det du sannsynligvis trenger): https://stackoverflow.com/questions/5816417/how-to-properly-express-jpql-join-fetch-with-where-clause-as-jpa-2-criteriaq
**Oppdatering
Hvis du ikke bruker fetch
og avdelingene fortsetter å bli returnert, er det fordi din mapping mellom Employee og Department (en @OneToMany
) er satt med FetchType.EAGER
. I dette tilfellet vil alle HQL-spørringer (med fetch
eller ikke) med FROM Employee
gi alle avdelinger. Husk at alle mapping *ToOne (@ManyToOne
og @OneToOne
) er EAGER som standard.
i denne lenken jeg nevnte før på kommentaren, les denne delen:
En "fetch" sammenføyning gjør det mulig for assosiasjoner eller samlinger av verdier å bli initialiseres sammen med sine overordnede objekter ved hjelp av et enkelt valg. Dette er spesielt nyttig når det gjelder en samling. Det overstyrer effektivt den ytre sammenføyningen og lazy-deklarasjonene i mappingfilen mapping-filen for assosiasjoner og samlinger.
dette "JOIN FETCH" vil ha sin effekt hvis du har (fetch = FetchType.LAZY) eiendom for en samling inne i entiteten (eksempel nedenfor).
Og det påvirker bare metoden for "når spørringen skal skje". Og du må også vite this:
hibernate har to ortogonale forestillinger: når hentes assosiasjonen og hvordan er det hentet. Det er viktig at du ikke forveksler dem. Vi bruker fetch for å justere ytelsen. Vi kan bruke lazy til å definere en kontrakt for hvilke data som alltid er tilgjengelige i en løsrevet forekomst av en bestemt klasse. klasse.
når hentes assosiasjonen - > din "FETCH" type
hvordan hentes den --> Join/select/Subselect/Batch
I ditt tilfelle vil FETCH bare ha effekt hvis du har department som et sett inne i Employee, omtrent slik i entiteten:
@OneToMany(fetch = FetchType.LAZY)
private Set<Department> department;
når du bruker
FROM Employee emp
JOIN FETCH emp.department dep
vil du få emp
og emp.dep
. Hvis du ikke bruker fetch, kan du fortsatt få emp.dep
, men hibernate vil behandle et nytt select til databasen for å få det settet med avdelinger.
så det er bare et spørsmål om ytelsesinnstilling, om du vil få alle resultatene (du trenger det eller ikke) i en enkelt spørring (ivrig henting), eller om du vil spørre det senere når du trenger det (lat henting).
Bruk ivrig henting når du trenger å hente små data med ett valg (én stor spørring). Eller bruk lazy fetching for å hente det du trenger senere (mange mindre spørringer).
Bruk fetch når:
det ikke finnes noen stor uønsket samling/mengde inne i den entiteten du er i ferd med å hente
kommunikasjonen fra applikasjonsserveren til databaseserveren er for lang og krever lang tid
du kan trenge denne samlingen senere når du ikke har tilgang til den (utenfor den transaksjonelle metoden/klassen)
Dherik: Jeg er ikke sikker på hva du sier, når du ikke bruker fetch vil resultatet være av typen: List<Object[ ]>
som betyr en liste over Object-tabeller og ikke en liste over Employee.
Object[0] refers an Employee entity
Object[1] refers a Departement entity
Når du bruker fetch, er det bare ett select, og resultatet er listen over Employee List<Employee>
som inneholder listen over avdelinger. Det overstyrer den late deklarasjonen av entiteten.