Nega so'rovlar keshi kerak
Xodimlarni olish jarayonini HQL bilan qayta yozamiz:
Employee director1 = session.createQuery("from Employee where id = 4").uniqueResult();
Employee director2 = session.createQuery("from Employee where id = 4").uniqueResult();
assertTrue(director1 != director2);
Shu turdagi so'rovlar natijalari birinchi yoki ikkinchi darajali keshlar tomonidan saqlanmaydi.
Bu aynan kesh so'rovlarini ishlatish mumkin bo'lgan joy. U ham default holatda o'chirilgan. Uni yoqish uchun konfiguratsion faylga quyidagi qatorni qo'shish kerak:
<property name="hibernate.cache.use_query_cache" value="true"/>
Lekin bu faqat yechimning yarmi. Biz kesh so'rovini yoqdik, lekin qaysi so'rovlar natijasini keshlashni xohlayotganimizni ko'rsatishimiz kerak. Bu Query so'roviga kiritilishi kerak:
Query query = session.createQuery("from Employee where id = 4");
query.setCacheable(true);
Employee director1 = query.uniqueResult();
Kesh so'rovi ikkinchi darajali keshga o'xshaydi. Lekin undan farqli ravishda, bu yerda keshlangan ma'lumotlar uchun kalit obyektning identifikatori emas, balki so'rov parametrlarining yig'indisidir. Va o'zi ma'lumotlar - bu so'rov mezonlariga mos keladigan obyektlar identifikatorlari. Shuning uchun bu keshi ikkinchi darajali kesh bilan birgalikda ishlatish ratsionaldir.
Keshi tozalash
Kesh bilan ishlashda muhim vazifalardan biri - keshlangan obyektlar o'zgarganligini kuzatish va ularni keshdan o'chirish (yoki yangilash). Hibernate buni juda yaxshi uddalaydi. Ba'zida hatto "har qanday noaniqlikda keshi tozala" qoidasi asosida harakat qiladi.
Farz qilaylik, foydalanuvchi ma'lumotlarini HQL orqali yangilamoqchisan:
Query query = session.createQuery("update Employee set name=’Alex’ where id = 4")
query. executeUpdate();
Hibernate bazada nima o'zgarganligini aniq bila olmaydi, lekin sen Employee turidagi obyektni o'zgartirayotganingni biladi. Shuning uchun, ushbu so'rov amalga oshgandan so'ng, Hibernate o'z keshidan umuman barcha Employee turidagi obyektlarni o'chiradi.
Lekin NativeQuery biroz qiziqarli ishlaydi:
Query nativeQuery = session.createNativeQuery("update employee set name=’Alex’ where id = 4")
nativeQuery.executeUpdate();
SQL-so'rov bazaga ishladi. Demak, bazadagi nimadir o'zgardi — so'rov executeUpdate() metodida chaqirildi. Shuning uchun bu holatda Hibernate biroz xavfsizlik ko'rib chiqadi va o'z keshidan umuman barcha turdagi obyektlarni o'chiradi.
Bu qanday? Sen zararsiz so'rov chaqirasan, Hibernate javoban barcha ma'lumotlarni keshdan o'chiradi! Bu albatta, agar u bazadan farq qiladigan obyektlarni saqlasa, yaxshiroq, lekin shu-narsa!
Shuning uchun Hibernate yaratuvchilari bu holatda Hibernate-ga yordam berish yo'lini tezda topishdi. Sen unga qaysi turdagi obyektlarni keshdan o'chirish kerakligini ko'rsatishing mumkin:
Query nativeQuery = session.createNativeQuery("update employee set name=’Alex’ where id = 4");
nativeQuery.unwrap(org.hibernate.SQLQuery.class).addSynchronizedEntityClass(Employee.class);
nativeQuery.executeUpdate();
Izoh. Native
select so'rovlar keshi
tozalamaydi, faqat insert, update, delete, protsedura chaqiriqlari va hokazo.
Keshni qo'lda tozalash
Ma'lum sabablarga ko'ra, sen obyektni keshdan o'zing o'chirmoqchi bo'lishing mumkin. Buni bir necha yo'l bilan amalga oshirish mumkin.
Izoh. Keshdagi obyektlar regionlar deb ataladigan guruhlarda saqlanadi. Default bo'yicha, region nomi klass nomi bilan bir xil. Shuning uchun, agar sen com.javarush.Employee turidagi obyektlarga ega bo'lsang, ularning barchasi “com.javarush.employee” nomli guruhda (regionda) saqlanadi.
Agar sen keshga kirishni xohlasang va u bilan nimadir qilmoqchi bo'lsang, buni SessionFactory obyekti va getCache() metodi yordamida amalga oshirish mumkin:
session.getSessionFactory().getCache().evictQueryRegion("com.javarush.employee”);
Agar sen barcha guruhlar (regionlar) ma'lumotlarini o'chirmoqchi bo'lsang, bunday so'rovni bajarish kerak:
session.getSessionFactory().getCache().evictAllRegions();
Agar bir obyektdan keshdan o'chirmoqchi bo'lsang, uning nomi (turi) va id sini berish kerak. Buni ikki yo'l bilan amalga oshirish mumkin:
session.getSessionFactory().getCache().evictEntityData("Employee”, 4);
session.getSessionFactory().getCache().evictEntityData(com.javarush.Employee.class, 4);
Siz shuningdek, ma'lum bir obyekt keshda mavjudligini tekshirishingiz mumkin:
session.getSessionFactory().getCache().containsEntity("Employee”, 4);
session.getSessionFactory().getCache().containsEntity(com.javarush.Employee.class, 4);
GO TO FULL VERSION