2.1 Menautkan di tingkat tabel
Kami telah melihat bagaimana Hibernate menyimpan koleksi di tabel tambahan. Sekarang mari kita cari tahu cara mengatur hubungan antara tabel lengkap yang menyimpan kelas Entitas nyata.
Ada empat jenis hubungan antara kelas Entitas di Hibernasi:
- satu -ke- satu
- satu -ke- banyak
- banyak -ke- satu
- banyak -ke- banyak
Dan kami akan memulai analisis dengan opsi paling sederhana - banyak -ke- satu .
Anda telah menemukan hubungan seperti itu antara tabel di SQL. Inilah yang biasanya terlihat seperti:
pengenal | nama | pekerjaan | gaji | usia | join_date |
---|---|---|---|---|---|
1 | Ivanov Ivan | Programmer | 100000 | 25 | 30-06-2012 |
2 | Petrov Petr | Programmer | 80000 | 23 | 12-08-2013 |
3 | Ivanov Sergey | Penguji | 40000 | tigapuluh | 01-01-2014 |
4 | Rabinovich Moisha | Direktur | 200000 | 35 | 12-05-2015 |
5 | Kirienko Anastasia | Manajer kantor | 40000 | 25 | 10-10-2015 |
6 | Vaska | Kucing | 1000 | 3 | 11-11-2018 |
tabel karyawan:
Tabel ini memiliki kolom berikut:
- id INT
- nama VARCHAR
- pendudukan VARCHAR
- gaji INT
- usia INT
- TANGGAL_gabung _
Dan seperti inilah tampilan tabel tugas , yang berisi tugas untuk karyawan:
pengenal | identitas pegawai | nama | tenggat waktu |
---|---|---|---|
1 | 1 | Perbaiki bug di frontend | 01-06-2022 |
2 | 2 | Perbaiki bug di backend | 15-06-2022 |
3 | 5 | Beli kopi | 01-07-2022 |
4 | 5 | Beli kopi | 01-08-2022 |
5 | 5 | Beli kopi | 01-09-2022 |
6 | (BATAL) | Membersihkan kantor | (BATAL) |
7 | 4 | Menikmati hidup | (BATAL) |
8 | 6 | Menikmati hidup | (BATAL) |
Tabel ini hanya memiliki 4 kolom:
- id – nomor tugas unik (dan baris dalam tabel);
- employee_id – ID karyawan dari tabel karyawan tempat tugas diberikan;
- nama – nama dan deskripsi tugas;
- tenggat waktu - waktu dimana tugas harus diselesaikan.
Kami melihat bahwa banyak baris dalam tabel tugas dapat merujuk ke satu entri dalam tabel karyawan. Hubungan tingkat tabel seperti itu disebut banyak-ke -satu.
2.2 Relasi ke level kelas Java
Selain komunikasi di tingkat tabel, Anda juga dapat mengatur komunikasi di tingkat kelas Entitas di Hibernasi. Ini dilakukan dengan anotasi @ManyToOne
.
Tapi pertama-tama, mari kita buat dua kelas: Employee dan EmployeeTask :
@Entity
@Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@Column(name="name")
public String name;
@Column(name="occupation")
public String occupation;
@Column(name="salary")
public Integer salary;
@Column(name="join_date")
public Date join;
}
Dan kelas kedua untuk menyimpan pekerjaan karyawan:
@Entity
@Table(name="task")
class EmployeeTask {
@Column(name="id")
public Integer id;
@Column(name="name")
public String description;
@Column(name="employee_id")
public Integer employeeId;
@Column(name="deadline")
public Date deadline;
}
Semua baik-baik saja dengan kelas-kelas ini, tetapi tidak ada hubungan di antara mereka yang mencerminkan fakta bahwa bidang employeeId dari kelas EmployeeTask merujuk ke bidang id dari kelas Employee. Sudah waktunya untuk memperbaikinya
2.3 anotasi @ManyToOne.
Pertama, di Java kita terbiasa mengoperasikan objek (dan referensi objek) daripada id mereka. Jadi pertama-tama, alih-alih bidang employeeId di kelas EmployeeTask, mari arahkan saja ke objek bertipe Employee. Inilah tampilan kelas baru kita:
@Entity
@Table(name="task")
class EmployeeTask {
@Column(name="id")
public Integer id;
@Column(name="name")
public String description;
@ManyToOne
@JoinColumn(name = "employee_id")
public Employee employee;
@Column(name="deadline")
public Date deadline;
}
Dengan bantuan anotasi @ManyToOne
, kami telah menunjukkan bahwa banyak objek EmployeeTask dapat merujuk ke satu objek bertipe Employee. Juga, dengan menggunakan anotasi @JoinColumn
, kami menunjukkan di kolom mana dari tabel kami id objek Karyawan disimpan.
2.4 Minta contoh
Dan sekarang mari kita tunjukkan beberapa contoh bagaimana Hibernate dapat bekerja dengan class terkait tersebut.
Skenario satu
Mari tulis kueri untuk mengetahui semua tugas yang telah diberikan kepada pengguna tertentu. Berikut tampilan kueri ini di HQL:
from EmployeeTask where employee.name = "Ivan Ivanovich"
Anda cukup merujuk ke bidang kelas dependen melalui titik. Sangat nyaman. Tapi mari kita tetap menulis kueri ini dalam bentuk kode Java:
String hql = "from EmployeeTask where employee.name = :username";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter("username", "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();
Skenario dua
Mari tulis kueri yang mengembalikan daftar karyawan yang memiliki tugas yang telah lewat waktu. Suatu tugas terlambat jika tenggat waktunya sudah lewat. Inilah tampilan kueri itu di SQL:
SELECT DISTINCT employee.*
FROM task JOIN employee ON task.employee_id = employee.id
WHERE task.deadline < CURDATE();
DISTINCT
digunakan 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 kita dapat menulis id, melainkan berisi bidang Karyawan tempat kita perlu menetapkan referensi ke objek bertipe Karyawan.
Employee director = session.get(Employee.class, 4);
String hql = "update EmployeeTask set employee = :user where employee is null";
Query<EmployeeTask> query = session.createQuery(hql, EmployeeTask.class);
query.setParameter("user", director);
query.executeUpdate();
GO TO FULL VERSION