3.1 Memetakan entitas dependen

Di SQL, Anda dapat menulis kueri menggunakan GABUNG. Apakah mungkin melakukan hal yang sama di HQL? Jawaban singkatnya adalah ya. Tapi jawaban lengkapnya akan lebih menarik.

Pertama, saat kita menulis JOIN di SQL, ini paling sering berarti bahwa satu tabel merujuk ke tabel lain. Misalnya, tabel tugas berisi kolom employee_id yang merujuk ke kolom id dari tabel employee.

Ketergantungan ini dapat dijelaskan menggunakan anotasi di Hibernate. Pertama, mari buat Entitas untuk tabel kita. Pertama, mari kita gambarkan tabel karyawan:

@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 tabel 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 saran. Mari kita lihat field employeeId pada contoh terakhir:

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

Apakah Anda memperhatikan sesuatu yang aneh? Jika belum, berarti Anda sudah membentuk cara berpikir dalam bahasa SQL.

Masalahnya adalah bahwa dalam bahasa Java, kami biasanya mendeskripsikan ketergantungan semacam itu dengan sedikit berbeda:

public Employee employee;

Kita tidak perlu menentukan id , kita biasanya hanya menentukan variabel yang menyimpan referensi ke objek Employee . Atau menyimpan nol jika tidak ada objek seperti itu.

Dan Hibernate memungkinkan kami untuk menggambarkan situasi seperti itu menggunakan anotasi:

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

Anotasi @ManyToOnememberi tahu Hibernate bahwa banyak entitas EmployeeTask dapat merujuk ke satu entitas Employee .

Dan anotasi @JoinColumnmenentukan nama kolom dari mana id akan diambil . Semua informasi lain yang diperlukan akan diambil dari anotasi kelas Karyawan.

Hasil akhir akan terlihat 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 di HQL

Dan sekarang mari kita lihat cara menulis kueri ke entitas terkait di HQL.

Situasi pertama.

Kami memiliki seorang karyawan (Karyawan) dan kami ingin mendapatkan daftar tugasnya. Inilah tampilan kueri itu di SQL:

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

Dan sekarang mari tulis kueri yang sama di HQL:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Kelas EmployeeTask memiliki field employee , dan memiliki field name , sehingga kueri ini akan berfungsi.

Situasi dua.

Kembalikan daftar karyawan yang memiliki tugas terlambat. Inilah tampilan kueri itu di SQL:

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

DISTINCTdigunakan karena bisa ada banyak tugas yang diberikan kepada satu pengguna.

Dan sekarang mari tulis kueri yang sama di HQL:

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

karyawan dalam kueri ini adalah bidang kelas EmployeeTask

Situasi tiga.

Tetapkan semua tugas yang belum ditetapkan kepada direktur. Permintaan SQL akan terlihat seperti ini:

UPDATE task SET employee_id = 4 WHERE employee_id IS NULL

Dan sekarang mari tulis kueri yang sama di HQL:

update EmployeeTask set employee = :user where employee is null

Permintaan terakhir adalah yang paling sulit. Kita harus memberikan ID, direktur, tetapi kelas EmployeeTask tidak berisi bidang tempat Anda dapat menulis id, melainkan berisi bidang Karyawan tempat Anda perlu menetapkan referensi ke objek bertipe Karyawan.

Di Hibernate, masalah ini diselesaikan dengan bantuan parameter kueri yang diteruskan ke objek Kueri. Dan di HQL sendiri, parameter tersebut ditulis melalui titik dua: :user. Tapi kita akan membicarakannya nanti.