@OneToOne

All lectures for UZ purposes
Daraja, Dars
Mavjud

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();

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION