ทำไมคุณถึงต้องการแคชแบบสอบถาม
ลองเขียนตัวอย่างใหม่โดยรับพนักงานใน HQL:
Employee director1 = session.createQuery("from Employee where id = 4").uniqueResult();
Employee director2 = session.createQuery("from Employee where id = 4").uniqueResult();
assertTrue(director1 != director2);
ผลลัพธ์ของแบบสอบถามดังกล่าวไม่ได้ถูกจัดเก็บโดยแคชระดับที่หนึ่งหรือสอง
นี่คือจุดที่ สามารถใช้ แคชแบบสอบถามได้ นอกจากนี้ยังปิดใช้งานตามค่าเริ่มต้น หากต้องการเปิดใช้งาน ให้เพิ่มบรรทัดต่อไปนี้ในไฟล์คอนฟิกูเรชัน:
<property name="hibernate.cache.use_query_cache" value="true"/>
แต่นี่เป็นเพียงครึ่งเดียวของการแก้ปัญหา เราได้เปิดใช้งานแคชของแบบสอบถาม แต่เราต้องระบุผลลัพธ์ของแบบสอบถามที่เราต้องการแคชด้วย สิ่งนี้จะต้องเขียนในแบบสอบถาม:
Query query = session.createQuery("from Employee where id = 4");
query.setCacheable(true);
Employee director1 = query.uniqueResult();
แคชแบบสอบถามคล้ายกับแคชระดับที่สอง แต่ไม่เหมือนตรงที่คีย์ของข้อมูลแคชไม่ใช่ตัวระบุวัตถุ แต่เป็นชุดของพารามิเตอร์การสืบค้น และข้อมูลเป็นตัวระบุของวัตถุที่ตรงกับเกณฑ์การค้นหา ดังนั้นจึงมีเหตุผลที่จะใช้แคชนี้กับแคชระดับที่สอง
การล้างแคช
ภารกิจสำคัญประการหนึ่งเมื่อทำงานกับแคชคือต้องแน่ใจว่าอ็อบเจ็กต์ที่แคชเปลี่ยนแปลงและลบออกจากแคช (หรืออัปเดตวัตถุเหล่านั้น) ไฮเบอร์เนตทำได้ดีมาก บางครั้งดูเหมือนว่าเขาได้รับคำแนะนำจากกฎ "ล้างแคชในสถานการณ์ที่เข้าใจยาก"
สมมติว่าคุณต้องการอัปเดตข้อมูลผู้ใช้ผ่าน HQL:
Query query = session.createQuery("update Employee set name=’Alex’ where id = 4")
query. executeUpdate();
ไฮเบอร์เนตไม่สามารถรู้ได้อย่างแน่ชัดว่ามีอะไรเปลี่ยนแปลงในฐานข้อมูล แต่รู้ว่าคุณกำลังเปลี่ยนวัตถุพนักงาน ดังนั้น หลังจากดำเนินการค้นหานี้ Hibernate จะลบออบเจกต์ประเภท Employee ทั้งหมดออกจากแคช
แต่ NativeQuery นั้นน่าสนใจยิ่งกว่า:
Query nativeQuery = session.createNativeQuery("update employee set name=’Alex’ where id = 4")
nativeQuery.executeUpdate();
มีการเรียกใช้แบบสอบถาม SQL ดั้งเดิมไปยังฐานข้อมูลแล้ว ซึ่งหมายความว่ามีบางอย่างเปลี่ยนแปลงในฐานข้อมูล - คำขอถูกเรียกใน เมธอด executeUpdate( ) ดังนั้น ในกรณีนี้ ไฮเบอร์เนตจะเล่นอย่างปลอดภัยและลบออบเจกต์ทั้งหมดทุกประเภทออก จากแคช
คุณชอบสิ่งนั้นอย่างไร? คุณเรียกคำขอที่ไม่เป็นอันตราย และไฮเบอร์เนตตอบสนองจะลบข้อมูลทั้งหมดออกจากแคช! แน่นอนว่ามันดีกว่าที่เขาเก็บวัตถุที่แตกต่างจากฐาน แต่ก็นั่นแหละ!
ดังนั้นผู้สร้าง Hibernate จึงหาวิธีช่วย Hibernate ในกรณีนี้ได้อย่างรวดเร็ว คุณสามารถบอกได้ว่าจะลบเอนทิตีประเภทใดออกจากแคช:
Query nativeQuery = session.createNativeQuery("update employee set name=’Alex’ where id = 4");
nativeQuery.unwrap(org.hibernate.SQLQuery.class).addSynchronizedEntityClass(Employee.class);
nativeQuery.executeUpdate();
หมายเหตุ . เคียวรีแบบเลือกเนที ฟ ไม่ล้างแคชเฉพาะการแทรก อัพเดต ลบ การเรียกใช้โพรซีเดอร์ ฯลฯ
การล้างแคชด้วยตนเอง
ด้วยเหตุผลบางประการ คุณอาจต้องการลบวัตถุออกจากแคชด้วยตัวคุณเอง สามารถทำได้หลายวิธี
หมายเหตุ _ อ็อบเจกต์ในแคชถูกจัดเก็บไว้ในกลุ่มที่เรียกว่าภูมิภาค ตามค่าเริ่มต้น ชื่อภูมิภาคจะเหมือนกับชื่อคลาส ดังนั้น หากคุณมีอ็อบเจ็กต์ประเภทcom.codegym.Employeeอ็อบเจ็กต์ทั้งหมดจะถูกจัดเก็บไว้ในกลุ่ม (ภูมิภาค) ด้วยชื่อ " com.codegym.employee "
หากคุณต้องการเข้าถึงแคชและทำบางอย่างกับแคช คุณสามารถทำได้โดยใช้วัตถุ SessionFactory และเมธอด getCache () :
session.getSessionFactory().getCache().evictQueryRegion("com.codegym.employee”);
หากคุณต้องการลบข้อมูลจากทุกกลุ่ม (ภูมิภาค) คุณต้องเรียกใช้แบบสอบถามต่อไปนี้:
session.getSessionFactory().getCache().evictAllRegions();
ในการลบวัตถุหนึ่งออกจากแคช คุณต้องส่งชื่อ (ประเภท) และรหัสของวัตถุนั้น คุณสามารถทำได้สองวิธี:
session.getSessionFactory().getCache().evictEntityData("Employee”, 4);
session.getSessionFactory().getCache().evictEntityData(com.codegym.Employee.class, 4);
คุณยังสามารถตรวจสอบว่ามีวัตถุใดอยู่ในแคชหรือไม่:
session.getSessionFactory().getCache().containsEntity("Employee”, 4);
session.getSessionFactory().getCache().containsEntity(com.codegym.Employee.class, 4);
GO TO FULL VERSION