3.1 Memetakan entiti bergantung

Dalam SQL, anda boleh menulis pertanyaan menggunakan JOIN. Adakah mungkin untuk melakukan perkara yang sama di HQL? Jawapan ringkasnya ialah ya. Tetapi jawapan penuh akan menjadi lebih menarik.

Pertama, apabila kita menulis JOIN dalam SQL, ia selalunya bermakna satu jadual merujuk kepada jadual lain. Sebagai contoh, jadual tugas mengandungi lajur id_pekerja yang merujuk kepada lajur id jadual pekerja.

Kebergantungan ini boleh diterangkan menggunakan anotasi dalam Hibernate. Mula-mula, mari kita buat Entiti untuk jadual kita. Pertama, mari kita terangkan jadual pekerja:

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

Dan kelas EmployeeTask untuk jadual tugas :

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

Semuanya baik-baik saja, tetapi ada satu cadangan. Mari lihat medan employeeId dalam contoh terakhir:

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

Adakah anda perasan sesuatu yang pelik? Jika tidak, ini bermakna anda telah membentuk cara berfikir dalam bahasa SQL.

Masalahnya ialah dalam bahasa Java, kami biasanya menerangkan pergantungan sedemikian sedikit berbeza:

public Employee employee;

Kami tidak perlu menentukan id , kami biasanya hanya menentukan pembolehubah yang memegang rujukan kepada objek Pekerja . Atau menyimpan null jika tiada objek sedemikian.

Dan Hibernate membolehkan kami menerangkan situasi sedemikian menggunakan anotasi:

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

Anotasi @ManyToOnememberitahu Hibernate bahawa banyak entiti EmployeeTask boleh merujuk kepada satu entiti Pekerja .

Dan anotasi @JoinColumnmenentukan nama lajur dari mana id akan diambil . Semua maklumat lain yang diperlukan akan diambil daripada anotasi kelas Pekerja.

Keputusan akhir akan kelihatan seperti ini:

@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 Menggunakan join dalam HQL

Dan sekarang mari kita lihat cara menulis pertanyaan kepada entiti berkaitan dalam HQL.

Situasi pertama.

Kami mempunyai seorang pekerja (Pekerja) dan kami ingin mendapatkan senarai tugasnya. Begini rupa pertanyaan itu dalam SQL:

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

Dan sekarang mari kita tulis pertanyaan yang sama dalam HQL:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Kelas EmployeeTask mempunyai medan pekerja dan ia mempunyai medan nama , jadi pertanyaan ini akan berfungsi.

Situasi dua.

Kembalikan senarai pekerja yang mempunyai tugas tertunggak. Begini rupa pertanyaan itu dalam SQL:

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

DISTINCTdigunakan kerana terdapat banyak tugasan yang diberikan kepada satu pengguna.

Dan sekarang mari kita tulis pertanyaan yang sama dalam HQL:

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

pekerja dalam pertanyaan ini ialah medan kelas EmployeeTask

Situasi tiga.

Serahkan semua tugas yang belum diserahkan kepada pengarah. Pertanyaan SQL akan kelihatan seperti ini:

UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

Dan sekarang mari kita tulis pertanyaan yang sama dalam HQL:

update EmployeeTask set employee = :user where employee is null

Pertanyaan terakhir adalah yang paling sukar. Kami perlu lulus ID, pengarah, tetapi kelas EmployeeTask tidak mengandungi medan di mana anda boleh menulis id, sebaliknya ia mengandungi medan Pekerja di mana anda perlu menetapkan rujukan kepada objek jenis Pekerja.

Dalam Hibernate, masalah ini diselesaikan dengan bantuan parameter pertanyaan yang dihantar ke objek Pertanyaan. Dan dalam HQL sendiri, parameter tersebut ditulis melalui titik bertindih: :user. Tetapi kita akan bercakap tentang ini sedikit kemudian.