ไฮเบอร์เนต - การแคช

การแคชเป็นกลไกในการเพิ่มประสิทธิภาพของระบบ เป็นหน่วยความจำบัฟเฟอร์ที่อยู่ระหว่างแอปพลิเคชันและฐานข้อมูล หน่วยความจำแคชจัดเก็บรายการข้อมูลที่ใช้ล่าสุดเพื่อลดจำนวนการเข้าถึงฐานข้อมูลให้ได้มากที่สุด

การแคชมีความสำคัญต่อไฮเบอร์เนตเช่นกัน มันใช้รูปแบบการแคชหลายระดับตามที่อธิบายไว้ด้านล่าง -

แคชระดับแรก

แคชระดับแรกคือแคชเซสชันและเป็นแคชบังคับซึ่งการร้องขอทั้งหมดจะต้องผ่าน วัตถุเซสชันเก็บวัตถุไว้ภายใต้อำนาจของตัวเองก่อนที่จะส่งไปยังฐานข้อมูล

หากคุณออกการอัปเดตหลายรายการให้กับออบเจ็กต์ Hibernate จะพยายามชะลอการอัปเดตให้นานที่สุดเพื่อลดจำนวนคำสั่ง Update SQL ที่ออก หากคุณปิดเซสชันอ็อบเจ็กต์ทั้งหมดที่แคชไว้จะสูญหายและยังคงอยู่หรืออัพเดตในฐานข้อมูล

แคชระดับที่สอง

แคชระดับที่สองเป็นแคชทางเลือกและแคชระดับแรกจะได้รับการปรึกษาเสมอก่อนที่จะพยายามค้นหาวัตถุในแคชระดับที่สอง แคชระดับที่สองสามารถกำหนดค่าตามคลาสและต่อคอลเลกชันและส่วนใหญ่รับผิดชอบในการแคชอ็อบเจ็กต์ข้ามเซสชัน

แคชของบุคคลที่สามสามารถใช้กับ Hibernate ได้ อันorg.hibernate.cache.CacheProvider มีการจัดเตรียมอินเทอร์เฟซซึ่งจะต้องดำเนินการเพื่อให้ Hibernate มีส่วนจัดการกับการใช้งานแคช

แคชระดับการสืบค้น

ไฮเบอร์เนตยังใช้แคชสำหรับชุดผลลัพธ์การสืบค้นที่รวมอย่างใกล้ชิดกับแคชระดับที่สอง

นี่เป็นคุณลักษณะที่เป็นทางเลือกและต้องการพื้นที่แคชฟิสิคัลเพิ่มเติมอีกสองพื้นที่ซึ่งเก็บผลลัพธ์ของคิวรีที่แคชไว้และการประทับเวลาเมื่อตารางได้รับการอัปเดตครั้งล่าสุด สิ่งนี้มีประโยชน์สำหรับแบบสอบถามที่เรียกใช้บ่อยด้วยพารามิเตอร์เดียวกันเท่านั้น

แคชระดับที่สอง

ไฮเบอร์เนตใช้แคชระดับแรกตามค่าเริ่มต้นและคุณไม่ต้องทำอะไรเพื่อใช้แคชระดับแรก ตรงไปที่แคชระดับสองที่เป็นทางเลือก ไม่ใช่ทุกคลาสที่ได้รับประโยชน์จากการแคชดังนั้นสิ่งสำคัญคือต้องสามารถปิดใช้งานแคชระดับที่สองได้

แคชระดับที่สองของไฮเบอร์เนตถูกตั้งค่าในสองขั้นตอน ขั้นแรกคุณต้องตัดสินใจว่าจะใช้กลยุทธ์ใดพร้อมกัน หลังจากนั้นคุณกำหนดค่าการหมดอายุแคชและแอ็ตทริบิวต์แคชฟิสิคัลโดยใช้ผู้ให้บริการแคช

กลยุทธ์การทำงานพร้อมกัน

กลยุทธ์การทำงานพร้อมกันเป็นสื่อกลางซึ่งมีหน้าที่จัดเก็บรายการข้อมูลในแคชและดึงข้อมูลเหล่านั้นจากแคช หากคุณกำลังจะเปิดใช้งานแคชระดับที่สองคุณจะต้องตัดสินใจสำหรับแต่ละคลาสและคอลเลคชันแบบถาวรซึ่งจะใช้กลยุทธ์แคชพร้อมกันที่จะใช้

  • Transactional - ใช้กลยุทธ์นี้สำหรับข้อมูลที่อ่านเป็นส่วนใหญ่ซึ่งมีความสำคัญในการป้องกันข้อมูลเก่าในธุรกรรมพร้อมกันในกรณีที่ไม่ค่อยเกิดขึ้นกับการอัปเดต

  • Read-write - ใช้กลยุทธ์นี้อีกครั้งสำหรับข้อมูลที่อ่านเป็นส่วนใหญ่ซึ่งเป็นสิ่งสำคัญในการป้องกันข้อมูลเก่าในธุรกรรมพร้อมกันในกรณีที่ไม่ค่อยเกิดขึ้นกับการอัปเดต

  • Nonstrict-read-write- กลยุทธ์นี้ไม่รับประกันความสอดคล้องระหว่างแคชและฐานข้อมูล ใช้กลยุทธ์นี้หากข้อมูลแทบจะไม่เคยเปลี่ยนแปลงและความเป็นไปได้เล็กน้อยที่ข้อมูลจะเก่าไม่ใช่เรื่องสำคัญ

  • Read-only- กลยุทธ์การทำงานพร้อมกันที่เหมาะสมสำหรับข้อมูลซึ่งไม่เคยเปลี่ยนแปลง ใช้เพื่ออ้างอิงข้อมูลเท่านั้น

หากเราจะใช้การแคชระดับที่สองสำหรับไฟล์ Employee ให้เราเพิ่มองค์ประกอบการทำแผนที่ที่จำเป็นเพื่อบอกให้ Hibernate แคชอินสแตนซ์ของพนักงานโดยใช้กลยุทธ์การอ่าน - เขียน

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 
<hibernate-mapping>
   <class name = "Employee" table = "EMPLOYEE">
      
      <meta attribute = "class-description">
         This class contains the employee detail. 
      </meta>
      
      <cache usage = "read-write"/>
      
      <id name = "id" type = "int" column = "id">
         <generator class="native"/>
      </id>
      
      <property name = "firstName" column = "first_name" type = "string"/>
      <property name = "lastName" column = "last_name" type = "string"/>
      <property name = "salary" column = "salary" type = "int"/>
      
   </class>
</hibernate-mapping>

แอ็ตทริบิวต์ use = "read-write" บอกให้ Hibernate ใช้กลยุทธ์การอ่าน - เขียนพร้อมกันสำหรับแคชที่กำหนด

ผู้ให้บริการแคช

ขั้นตอนต่อไปของคุณหลังจากพิจารณากลยุทธ์การทำงานพร้อมกันแล้วคุณจะใช้คลาสผู้สมัครแคชของคุณเพื่อเลือกผู้ให้บริการแคช ไฮเบอร์เนตบังคับให้คุณเลือกผู้ให้บริการแคชรายเดียวสำหรับแอปพลิเคชันทั้งหมด

ซีเนียร์ ชื่อแคชและคำอธิบาย
1

EHCache

สามารถแคชในหน่วยความจำหรือบนดิสก์และการแคชแบบคลัสเตอร์และรองรับแคชผลการค้นหาไฮเบอร์เนตที่เป็นทางเลือก

2

OSCache

รองรับการแคชไปยังหน่วยความจำและดิสก์ใน JVM เดียวพร้อมชุดนโยบายการหมดอายุและการสนับสนุนแคชแบบสอบถาม

3

warmCache

แคชคลัสเตอร์ตาม JGroups ใช้การยกเลิกการใช้งานแบบคลัสเตอร์ แต่ไม่รองรับแคชแบบสอบถามไฮเบอร์เนต

4

JBoss Cache

แคชคลัสเตอร์ที่จำลองแบบทรานแซคชันเต็มรูปแบบยังขึ้นอยู่กับไลบรารีมัลติคาสต์ JGroups สนับสนุนการจำลองแบบหรือการทำให้เป็นโมฆะการสื่อสารแบบซิงโครนัสหรืออะซิงโครนัสและการล็อกในแง่ดีและแง่ร้าย รองรับแคชแบบสอบถามไฮเบอร์เนต

ผู้ให้บริการแคชทุกรายไม่สามารถใช้งานได้กับทุกกลยุทธ์ที่เกิดขึ้นพร้อมกัน เมทริกซ์ความเข้ากันได้ต่อไปนี้จะช่วยให้คุณเลือกชุดค่าผสมที่เหมาะสม

กลยุทธ์ / ผู้ให้บริการ อ่านเท่านั้น ไม่เข้มงวดอ่านเขียน อ่านเขียน การทำธุรกรรม
EHCache X X X  
OSCache X X X  
SwarmCache X X    
แคช JBoss X     X

คุณจะระบุผู้ให้บริการแคชในไฟล์คอนฟิกูเรชัน hibernate.cfg.xml เราเลือก EHCache เป็นผู้ให้บริการแคชระดับที่สองของเรา -

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
   
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
   
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>
   
      <!-- Assume students is the database name -->
   
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost/test
      </property>
   
      <property name = "hibernate.connection.username">
         root
      </property>
   
      <property name = "hibernate.connection.password">
         root123
      </property>
   
      <property name = "hibernate.cache.provider_class">
         org.hibernate.cache.EhCacheProvider
      </property>
   
      <!-- List of XML mapping files -->
      <mapping resource = "Employee.hbm.xml"/>
   
   </session-factory>
</hibernate-configuration>

ตอนนี้คุณต้องระบุคุณสมบัติของพื้นที่แคช EHCache มีไฟล์กำหนดค่าของตัวเองehcache.xmlซึ่งควรอยู่ใน CLASSPATH ของแอปพลิเคชัน การกำหนดค่าแคชใน ehcache.xml สำหรับคลาส Employee อาจมีลักษณะดังนี้ -

<diskStore path="java.io.tmpdir"/>

<defaultCache
maxElementsInMemory = "1000"
eternal = "false"
timeToIdleSeconds = "120"
timeToLiveSeconds = "120"
overflowToDisk = "true"
/>

<cache name = "Employee"
maxElementsInMemory = "500"
eternal = "true"
timeToIdleSeconds = "0"
timeToLiveSeconds = "0"
overflowToDisk = "false"
/>

ตอนนี้เราได้เปิดใช้งานการแคชระดับที่สองสำหรับคลาสพนักงานและไฮเบอร์เนตแล้วตอนนี้เข้าสู่แคชระดับที่สองเมื่อใดก็ตามที่คุณไปที่พนักงานหรือเมื่อคุณโหลดพนักงานด้วยตัวระบุ

คุณควรวิเคราะห์คลาสทั้งหมดของคุณและเลือกกลยุทธ์การแคชที่เหมาะสมสำหรับแต่ละคลาส ในบางครั้งการแคชระดับที่สองอาจลดระดับประสิทธิภาพของแอปพลิเคชัน ดังนั้นขอแนะนำให้เปรียบเทียบแอปพลิเคชันของคุณก่อนโดยไม่ต้องเปิดใช้งานการแคชและเปิดใช้งานการแคชที่เหมาะสมและตรวจสอบประสิทธิภาพในภายหลัง หากการแคชไม่ได้ปรับปรุงประสิทธิภาพของระบบแสดงว่าไม่มีจุดใดในการเปิดใช้งานการแคชประเภทใด ๆ

แคชระดับการสืบค้น

ในการใช้แคชแบบสอบถามก่อนอื่นคุณต้องเปิดใช้งานโดยใช้ไฟล์ hibernate.cache.use_query_cache="true"คุณสมบัติในไฟล์คอนฟิกูเรชัน เมื่อตั้งค่าคุณสมบัตินี้เป็นจริงคุณทำให้ไฮเบอร์เนตสร้างแคชที่จำเป็นในหน่วยความจำเพื่อเก็บคิวรีและชุดตัวระบุ

ถัดไปในการใช้แคชแบบสอบถามคุณใช้เมธอด setCacheable (บูลีน) ของคลาส Query ตัวอย่างเช่น -

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
List users = query.list();
SessionFactory.closeSession();

ไฮเบอร์เนตยังรองรับการรองรับแคชแบบละเอียดมากผ่านแนวคิดของพื้นที่แคช พื้นที่แคชเป็นส่วนหนึ่งของแคชที่ตั้งชื่อให้

Session session = SessionFactory.openSession();
Query query = session.createQuery("FROM EMPLOYEE");
query.setCacheable(true);
query.setCacheRegion("employee");
List users = query.list();
SessionFactory.closeSession();

รหัสนี้ใช้วิธีการบอกให้ Hibernate จัดเก็บและค้นหาคำค้นหาในพื้นที่แคชของพนักงาน