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.