3.1 Kartläggning av beroende enheter

I SQL kan du skriva frågor med JOIN. Är det möjligt att göra samma sak i HQL? Det korta svaret är ja. Men det fullständiga svaret blir mer intressant.

För det första, när vi skriver en JOIN i SQL betyder det oftast att en tabell refererar till en annan tabell. Till exempel innehåller uppgiftstabellen en anställd_id-kolumn som hänvisar till id-kolumnen i anställdtabellen.

Detta beroende kan beskrivas med anteckningar i Hibernate. Låt oss först skapa entiteter för våra tabeller. Låt oss först beskriva personaltabellen:

@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;
}

Och EmployeeTask -klassen för uppgiftstabellen :

@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;
}

Allt är bra, men det finns ett förslag. Låt oss titta på fältet anställd-ID i det sista exemplet:

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

Märker du något konstigt? Om inte, så betyder det att du redan har bildat ett sätt att tänka i SQL-språket.

Saken är den att i Java-språket brukar vi beskriva ett sådant beroende lite annorlunda:

public Employee employee;

Vi behöver inte ange ett id , vi brukar bara specificera en variabel som innehåller en referens till Employee -objektet . Eller lagrar null om det inte finns något sådant objekt.

Och Hibernate låter oss beskriva en sådan situation med hjälp av kommentarer:

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

Anteckningen @ManyToOnetalar om för Hibernate att många EmployeeTask- enheter kan hänvisa till en Employee- enhet .

Och anteckningen @JoinColumnanger namnet på den kolumn som id:t kommer ifrån . All annan nödvändig information kommer att hämtas från anteckningarna för klassen Anställd.

Det slutliga resultatet kommer att se ut så här:

@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 Använda join i HQL

Och låt oss nu titta på hur man skriver frågor till relaterade enheter i HQL.

Första situationen.

Vi har en anställd (Anställd) och vi vill få en lista över hans arbetsuppgifter. Så här skulle den frågan se ut i SQL:

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

Och låt oss nu skriva samma fråga i HQL:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Klassen EmployeeTask har ett anställdsfält och det har ett namnfält , så den här frågan kommer att fungera.

Situation två.

Returnera en lista över anställda som har försenade uppgifter. Så här skulle den frågan se ut i SQL:

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

DISTINCTanvänds eftersom det kan vara många uppgifter tilldelade en användare.

Och låt oss nu skriva samma fråga i HQL:

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

anställd i den här frågan är ett fält i klassen EmployeeTask

Situation tre.

Tilldela alla otilldelade uppgifter till regissören. SQL-frågan kommer att se ut så här:

UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

Och låt oss nu skriva samma fråga i HQL:

update EmployeeTask set employee = :user where employee is null

Den sista frågan är den svåraste. Vi måste skicka ID:t, director, men EmployeeTask-klassen innehåller inte ett fält där du kan skriva id, istället innehåller den ett Employee-fält där du behöver tilldela en referens till ett objekt av typen Employee.

I Hibernate löses detta problem med hjälp av frågeparametrar som skickas till Query-objektet. Och i själva HQL skrivs sådana parametrar genom ett kolon: :user. Men vi kommer att prata om detta lite senare.