3.1 Pagmamapa ng mga umaasang entity

Sa SQL, maaari kang magsulat ng mga query gamit ang JOIN. Posible bang gawin ang parehong sa HQL? Ang maikling sagot ay oo. Ngunit ang buong sagot ay magiging mas kawili-wili.

Una, kapag sumulat tayo ng JOIN sa SQL, kadalasang nangangahulugan ito na ang isang talahanayan ay tumutukoy sa isa pang talahanayan. Halimbawa, ang talahanayan ng gawain ay naglalaman ng isang column na employee_id na tumutukoy sa column ng id ng talahanayan ng empleyado.

Maaaring ilarawan ang dependency na ito gamit ang mga anotasyon sa Hibernate. Una, gumawa lang tayo ng Entity para sa ating mga table. Una, ilarawan natin ang talahanayan ng empleyado:

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

At ang klase ng EmployeeTask para sa talahanayan ng gawain :

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

Maayos ang lahat, ngunit may isang mungkahi. Tingnan natin ang field ng employeeId sa huling halimbawa:

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

May napapansin ka bang kakaiba? Kung hindi, nangangahulugan ito na nakabuo ka na ng paraan ng pag-iisip sa wikang SQL.

Ang bagay ay sa wikang Java, karaniwan naming inilalarawan ang gayong dependency na medyo naiiba:

public Employee employee;

Hindi namin kailangang tukuyin ang isang id , kadalasan ay tumutukoy lamang kami ng isang variable na mayroong reference sa object ng Empleyado . O nag-iimbak ng null kung walang ganoong bagay.

At pinapayagan kami ng Hibernate na ilarawan ang ganoong sitwasyon gamit ang mga anotasyon:

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

Ang anotasyon @ManyToOneay nagsasabi sa Hibernate na maraming EmployeeTask entity ang maaaring sumangguni sa isang Employee entity .

At ang anotasyon @JoinColumnay tumutukoy sa pangalan ng column kung saan kukunin ang id . Ang lahat ng iba pang kinakailangang impormasyon ay kukunin mula sa mga anotasyon ng klase ng Empleyado.

Ang huling resulta ay magiging ganito:

@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 Paggamit ng pagsali sa HQL

At ngayon tingnan natin kung paano magsulat ng mga query sa mga kaugnay na entity sa HQL.

Unang sitwasyon.

Mayroon kaming isang empleyado (Empleyado) at nais naming makakuha ng isang listahan ng kanyang mga gawain. Narito kung ano ang magiging hitsura ng query na iyon sa SQL:

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

At ngayon isulat natin ang parehong query sa HQL:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Ang EmployeeTask class ay may field ng empleyado , at mayroon itong field ng pangalan , kaya gagana ang query na ito.

Dalawang sitwasyon.

Ibalik ang isang listahan ng mga empleyado na may mga overdue na gawain. Narito kung ano ang magiging hitsura ng query na iyon sa SQL:

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

DISTINCTay ginagamit dahil maaaring maraming gawain na nakatalaga sa isang user.

At ngayon isulat natin ang parehong query sa HQL:

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

Ang empleyado sa query na ito ay isang field ng EmployeeTask class

Pangatlong sitwasyon.

Italaga ang lahat ng hindi nakatalagang gawain sa direktor. Ang SQL query ay magiging ganito:

UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

At ngayon isulat natin ang parehong query sa HQL:

update EmployeeTask set employee = :user where employee is null

Ang huling query ang pinakamahirap. Kailangan naming ipasa ang ID, direktor, ngunit ang EmployeeTask class ay hindi naglalaman ng field kung saan maaari kang magsulat ng id, sa halip ay naglalaman ito ng Employee field kung saan kailangan mong magtalaga ng reference sa isang object ng uri ng Employee.

Sa Hibernate, ang problemang ito ay nalutas sa tulong ng mga parameter ng query na ipinasa sa Query object. At sa HQL mismo, ang mga naturang parameter ay nakasulat sa pamamagitan ng isang colon: :user. Ngunit pag-uusapan natin ito sa ibang pagkakataon.