3.1 Kartlegging av avhengige enheter

I SQL kan du skrive spørringer ved å bruke JOIN. Er det mulig å gjøre det samme i HQL? Det korte svaret er ja. Men det fullstendige svaret vil være mer interessant.

For det første, når vi skriver en JOIN i SQL, betyr det oftest at en tabell refererer til en annen tabell. For eksempel inneholder oppgavetabellen en ansatt_id-kolonne som refererer til id-kolonnen i ansatttabellen.

Denne avhengigheten kan beskrives ved hjelp av merknader i dvalemodus. Først, la oss bare lage entiteter for bordene våre. La oss først beskrive ansatttabellen:

@Entity
@Table(name="employee")
class Employee {
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String name;

   @Column(name="salary")
   public Integer salary;

   @Column(name="join_date")
   public Date joinDate;
}

Og EmployeeTask -klassen for oppgavetabellen :

@Entity
@Table(name="task")
class EmployeeTask {
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String name;

   @Column(name="employee_id")
   public Integer employeeId;

   @Column(name="deadline")
   public Date deadline;
}

Alt er bra, men det er ett forslag. La oss se på ansatt-ID- feltet i det siste eksemplet:

@Column(name="employee_id")
public Integer employeeId;

Merker du noe rart? Hvis ikke, betyr dette at du allerede har dannet deg en måte å tenke på i SQL-språket.

Saken er at i Java-språket beskriver vi vanligvis en slik avhengighet litt annerledes:

public Employee employee;

Vi trenger ikke spesifisere en id , vi spesifiserer vanligvis bare en variabel som inneholder en referanse til Employee- objektet . Eller lagrer null hvis det ikke finnes et slikt objekt.

Og Hibernate lar oss beskrive en slik situasjon ved å bruke merknader:

@ManyToOne
@JoinColumn(name="employee_id", nullable=true)
public Employee employee;

Merknaden @ManyToOneforteller Hibernate at mange EmployeeTask- enheter kan referere til én Employee- enhet .

Og merknaden @JoinColumnspesifiserer navnet på kolonnen som ID-en skal hentes fra . All annen nødvendig informasjon vil bli hentet fra merknadene til Ansattklassen.

Det endelige resultatet vil se slik ut:

@Entity
@Table(name="task")
class EmployeeTask
{
   @Column(name="id")
   public Integer id;

   @Column(name="name")
   public String name;

   @ManyToOne
   @JoinColumn(name="employee_id", nullable=true)
   public Employee employee;

   @Column(name="deadline")
   public Date deadline;
}

3.2 Bruke join i HQL

Og la oss nå se på hvordan du skriver spørringer til relaterte enheter i HQL.

Første situasjon.

Vi har en ansatt (Ansatt) og vi ønsker å få en liste over hans oppgaver. Slik vil spørringen se ut i SQL:

SELECT task.* FROM task JOIN employee ON task.employee_id = employee.id
WHERE employee.name = "Ivan Ivanovich";

Og la oss nå skrive den samme spørringen i HQL:

from EmployeeTask where employee.name = "Ivan Ivanovich"

EmployeeTask- klassen har et ansattfelt , og den har et navnefelt , så denne spørringen vil fungere.

Situasjon to.

Returner en liste over ansatte som har forfalte oppgaver. Slik vil spørringen se ut i SQL:

SELECT DISTINCT employee.*
FROM task JOIN employee ON task.employee_id = employee.id
WHERE task.deadline < CURDATE();

DISTINCTbrukes fordi det kan være mange oppgaver tildelt én bruker.

Og la oss nå skrive den samme spørringen i HQL:

select distinct employee from EmployeeTask where deadline < CURDATE();

ansatt i denne spørringen er et felt i EmployeeTask -klassen

Situasjon tre.

Tildel alle ikke-tildelte oppgaver til direktøren. SQL-spørringen vil se slik ut:

UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

Og la oss nå skrive den samme spørringen i HQL:

update EmployeeTask set employee = :user where employee is null

Det siste søket er det vanskeligste. Vi må sende ID-en, direktør, men EmployeeTask-klassen inneholder ikke et felt der du kan skrive id, i stedet inneholder den et Employee-felt hvor du må tilordne en referanse til et objekt av typen Employee.

I Hibernate løses dette problemet ved hjelp av spørringsparametere som sendes til Query-objektet. Og i selve HQL skrives slike parametere gjennom et kolon: :user. Men vi skal snakke om dette litt senere.