5.1 Turli xil bitta-bitta bog'lanish shakllari
Yana bir qiziqarli va juda o'ziga xos holat bor, u Entity-sinflar orasidagi munosabatlarda qo'llaniladi - bu bitta-bitta bog'lanish.
Bu holatni juda o'ziga xos deb atayman, chunki bu asosan Java obyektlari bilan bog'liq, ma'lumotlar bazasi bilan emas. Ma'lumotlar bazasida jadvallar orasidagi bog'lanishning atigi ikki xil varianti mavjud:
- Jadval satri boshqa jadvallar uchun id-ga havola saqlaydi.
- Ko'pdan-ko'pga bog'lanish uchun xizmat jadvallari ishlatiladi.
Lekin Entity-sinflar bilan bir nechta annotatsiyalar orqali tasvirlanadigan variantlar bo'lishi mumkin:
- @Embedded
- Bir tomonlama OneToOne
- Ikki tomonlama OneToOne
- @MapsId
Quyida eng mashhur bo'lganlarini ko'rib chiqamiz.
5.2 @Embedded
Eng oddiy one-to-one bog'lanish variantini allaqachon ko'rib chiqdik - bu @Embedded annotatsiyasi. Bu holatda, ikkala sinf ham ma'lumotlar bazasidagi bitta jadvalda saqlanadi.
Misol uchun, foydalanuvchining manzilini UserAddress sinfida saqlamoqchimiz:
@Embeddable
class UserAddress {
@Column(name="user_address_country") public String country; @Column(name="user_address_city") public String city; @Column(name="user_address_street") public String street; @Column(name="user_address_home") public String home;
}
Keyin esa, bu manzilni User sinfida maydon sifatida qo'shish kifoya:
@Entity @Table(name="user")
class User {
@Column(name="id")
public Integer id;
@Embedded
public UserAddress address;
@Column(name="created_date")
public Date createdDate;
}
Boshqa hamma narsani Hibernate bajadi: ma'lumotlar bitta jadvalda saqlanadi, lekin HQL-so'rovlarni yozishda aynan sinf maydonlari bilan ishlash kerak bo'ladi.
HQL-so'rovning misoli:
select from User where address.city = 'Paris'
5.3 Bir tomonlama OneToOne
Endi quyidagi vaziyatni tasavvur qiling: bizda employee va task jadvali bor, task employee-ga bog'langan. Ammo biz aniq bilamizki, bir foydalanuvchiga maksimum bitta task tayinlanishi mumkin. Ushbu vaziyatni tasvirlash uchun @OneToOne annotatsiyasidan foydalanishimiz mumkin.
Misol:
@Entity @Table(name="task")
class EmployeeTask {
@Column(name="id")
public Integer id;
@Column(name="name")
public String description;
@OneToOne @JoinColumn(name = "employee_id")
public Employee employee;
@Column(name="deadline")
public Date deadline;
}
Hibernate nafaqat bir taskga bir user, balki bir userga ham bitta task borligini ham kuzatadi. Boshqa jihatlari @ManyToOne bilan deyarli bir xil.
5.4 Ikki tomonlama OneToOne
Oldingi variant biroz qiyinchilik tug'dirishi mumkin, chunki ko'pincha taskga xodim tayinlashdan tashqari, xodimga ham task berishni xohlaysiz.
Buning uchun EmployeeTask maydonini Employee sinfiga qo'shish va unga to'g'ri annotatsiyalar o'rnatish mumkin.
@Entity @Table(name="employee")
class Employee {
@Column(name="id")
public Integer id;
@OneToOne(cascade = CascadeType.ALL, mappedBy="employee")
private EmployeeTask task;
}
Muhim! employee jadvalida task_id maydoni yo'q, buning o'rniga task jadvalidagi employee_id maydoni orqali jadvallar orasida bog'lanish o'rnatiladi.
Obyektlar orasidagi bog'lanishni o'rnatish quyidagi tarzda amalga oshiriladi:
Employee director = session.find(Employee.class, 4);
EmployeeTask task = session.find(EmployeeTask.class, 101);
task.employee = director;
director.task = task;
session.update(task);
session.flush();
Bog'lanishni o'chirish uchun, ikkala obyektdan ham havolani olib tashlash kerak:
Employee director = session.find(Employee.class, 4);
EmployeeTask task = director.task;
task.employee = null;
session.update(task);
director.task = null;
session.update(director);
session.flush();
GO TO FULL VERSION