Ob'ektni o'chirish

All lectures for UZ purposes
Daraja, Dars
Mavjud

remove() metodi yordamida o'chirish

Nihoyat, ob'ektni o'chirishni ko'rib chiqamiz. Aslida, malumotlar bazasidan ob'ektlarni o'chirish juda oson, lekin aytishga hojat yo'q, o'ziga xos xususiyatlar mavjud. Bunday xususiyatlar olti xil:

  • remove() metodi yordamida o'chirish
  • Kompaniya uchun o'chirish
  • Orphan bo'yicha o'chirish
  • JPQL orqali o'chirish
  • NativeQuery orqali o'chirish
  • softDeleted()

Va eng aniq yechimdan - remove() metodini chaqirishdan boshlaymiz.


User user = new User();
user.setName("Kolyan");
session.persist(user);  // ob'ektni bazaga qo'shamiz
session.flush(); 
session.clear();  // sessiyani yopamiz
 
user = (User) session.find(User.class, user.getId() ); // ob'ektni bazadan qayta olamiz
session.remove(user);
session.flush(); 
session.clear();  // sessiyani yopamiz
 
// bu yerda ob'ekt haqiqatda o'chirilgan.

Bazada haqiqiy operatsiya flush() metodi chaqirilgandan keyin yoki tranzaksiya yopilgandan keyin bajariladi.

Kaskadli o'chirish

SQL o'rganganimizda, bog'langan jadvallar uchun CONSTRAINT yozish mumkinligini eslaysizmi. Va ulardan biri shunday yozilgan edi:


CONSTRAINT ONDELETE REMOVE

Buning ma'nosi shunda ediki, agar bizda qiz jadvallarni o'z ichiga olgan jadval mavjud bo'lsa, ota-entiteti o'chirilganda uning barcha qiz entitetlari o'chirilishi kerak edi.

Faraz qilaylik, biz foydalanuvchining shaxsiy ma'lumotlarini saqlaymiz va bazada CONSTRAINT ni shunday sozladikki, foydalanuvchi o'chirilganda bu ma'lumotlar ham o'chiriladi. Keyin biz faqat ota-ob'ektni o'chirishimiz kerak va barcha qiz ob'ektlar bazada o'chiriladi:


User user = new User();
UserPrivateInfo info = new UserPrivateInfo();
user.setPrivateInfo(info);
session.persist(user);  // ob'ektni bazaga qo'shamiz, shuningdek bazaga info ob'ekt ham saqlanadi
session.flush(); 
session.clear();  // sessiyani yopamiz
 
user = (User) session.find(User.class, user.getId() ); // ob'ektni bazadan qayta olamiz
session.remove(user);
session.flush(); 
session.clear();  // sessiyani yopamiz
 
// bu yerda user va info ob'ektlar bazadan haqiqatda o'chirilgan.

Orphan bo'yicha o'chirish

Yana bir turdagi o'chirish mavjud bo'lib, u Orphan bo'yicha o'chirish deb ataladi. Bu oldingi variantga o'xshaydi. Qiz entiteti, ota-entitet bilan aloqasi uzilganda o'chiriladi. Shu bilan birga, ota-entitet odatda o'chirilmaydi.

Faraz qilaylik, bizda foydalanuvchi bor va unda xabarlar ro'yxati mavjud:


User user = new User();
UserMessage message = new UserMessage();
user.getMessageList().add(message);
session.persist(user);  // ob'ektni bazaga qo'shamiz, shuningdek bazaga message ob'ekt ham saqlanadi
session.flush(); 
session.clear();  // sessiyani yopamiz
 
user = (User) session.find(User.class, user.getId() ); // ob'ektni bazadan qayta olamiz
UserMessage message2 = user.getMessageList().get(0); // foydalanuvchi xabarini olamiz
user.getMessageList().remove(message2);  // xabarni ro'yxatdan o'chiramiz
session.flush(); 
session.clear();  // sessiyani yopamiz
 
// bu yerda message2 ob'ekt bazadan haqiqatda o'chirilgan

Yana bir muhim nuqtai nazar shundaki, agar biz Hibernate bu xatti-harakatni amalga oshirishi uchun, uni ikki entitetni bog'lashda annotatsiyalar yordamida aniq ko'rsatish kerak:


@Entity
public class User {
 
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private List<UserMessage> messageList = new ArrayList<UserMessage>();
 
}

JPQL orqali o'chirish

Ob'ektni o'chirishning yana bir qiziqarli usuli bu HQL (yoki JPQL) da so'rov yozishdir. Faqat oxirida executeUpdate() metodini chaqirishni unutmang, aks holda Hibernate read-only tranzaktsiya yaratadi va hech qanday o'chirish amalga oshmaydi.

Misol:


User user = new User();
session.persist(user);  // ob'ektni bazaga qo'shamiz
session.flush(); 
session.clear();  // sessiyani yopamiz
 
session.createQuery("delete from User where id = :id")
   .setParameter("id", user.getId())
   .executeUpdate();

Bazadagi o'zgarishlar mavjud Entity-ob'ektlarni hech qanday o'zgartirmaydi.

NativeQuery orqali o'chirish

Xuddi shunday NativeQuery orqali ham o'chirish mumkin.

Misol:


User user = new User();
session.persist(user);  // ob'ektni bazaga qo'shamiz
session.flush(); 
session.clear();  // sessiyani yopamiz
 
session.createNativeQuery("DELETE FROM user WHERE id = :id")
   .setParameter("id", user.getId())
   .executeUpdate();

Bazadagi o'zgarishlar mavjud Entity-ob'ektlarga hech qanday ta'sir ko'rsatmaydi.

Yumshoq o'chirish

Bazadagi ma'lumotlarni o'chirish o'rniga, ba'zida ularni o'chirilgan deb belgilash qulay bo'ladi. Bunday ma'lumotlar keyinchalik turli xil ssenariylarda ishtirok eta oladi. Birinchidan, bunday o'chirish oson qaytarilishi mumkin - qatorlar qayta tirik deb belgilanishi mumkin.

Ikkinchidan, bunday o'chirilgan ma'lumotlarni "arxivga qo'yish" foydali, chunki serverni boshqarish qonun bilan tartibga solinadigan holatlar mavjud va hokazo. Biroq, agar siz ma'lumotlaringizni o'chirilgan deb belgilasangiz, faqat siz ularning o'chirilganligini bilasiz. Hibernate esa, bu ma'lumotlarni topishda davom etadi, shuningdek ularni saralashda ishlatadi.

Shuning uchun Hibernate yaratuvchilari maxsus anotatsiyani o'ylab topgan, uning yordamida ob'ektlarni tirik deb belgilash mumkin edi. Misol:


@Entity
@Where(clause = "DELETED = 0") // barcha WHERE ga “AND DELETED = 0” qo'shiladi
public class User {
	// maydonlarni xaritalash
 
	@Column(name = "DELETED") // DELETED ustundagi qiymat 0 bo'lsa, yozuv tirik, agar 1 bo'lsa - o'lik
	private Integer deleted = 0; 
   
	// getter va setterlar
 
    public void softDeleted() {
    	this.deleted = 1; // yozuvni o'lik deb belgilaymiz
    }
}

Ob'ektni o'chirilgan deb belgilash uchun, unda softDeleted() metodini chaqirishingiz kifoya:


User user = new User();
session.persist(user);  // ob'ektni bazaga qo'shamiz
session.flush(); 
session.clear();  // sessiyani yopamiz
 
user = (User) session.find(User.class, user.getId() ); // ob'ektni bazadan qayta olamiz
user.softDeleted(); // ob'ektni o'chirilgan deb belgilaymiz
session.flush(); 
session.clear();  // sessiyani yopamiz
 
// endi bu ob'ekt Hibernate orqali topilmaydi
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION