ไฮเบอร์เนต - การแคช
การแคชเป็นกลไกในการเพิ่มประสิทธิภาพของระบบ เป็นหน่วยความจำบัฟเฟอร์ที่อยู่ระหว่างแอปพลิเคชันและฐานข้อมูล หน่วยความจำแคชจัดเก็บรายการข้อมูลที่ใช้ล่าสุดเพื่อลดจำนวนการเข้าถึงฐานข้อมูลให้ได้มากที่สุด
การแคชมีความสำคัญต่อไฮเบอร์เนตเช่นกัน มันใช้รูปแบบการแคชหลายระดับตามที่อธิบายไว้ด้านล่าง -
แคชระดับแรก
แคชระดับแรกคือแคชเซสชันและเป็นแคชบังคับซึ่งการร้องขอทั้งหมดจะต้องผ่าน วัตถุเซสชันเก็บวัตถุไว้ภายใต้อำนาจของตัวเองก่อนที่จะส่งไปยังฐานข้อมูล
หากคุณออกการอัปเดตหลายรายการให้กับออบเจ็กต์ 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 จัดเก็บและค้นหาคำค้นหาในพื้นที่แคชของพนักงาน