บทความนี้อธิบายถึงเทคโนโลยีการแคชในกรอบ Hibernate แบ่งปันสำหรับการอ้างอิงของคุณดังนี้:
แคชของเฟรมเวิร์กไฮเบอร์เนตแบ่งออกเป็นแคชเซสชันและแคช SessionFactory หรือที่เรียกว่าแคชระดับ 1 และแคชระดับ 2
แคชระดับ 1:
แคชระดับ 1 เป็นแคชระดับเซสชันซึ่งมีวงจรชีวิตสั้น ๆ สอดคล้องกับเซสชันได้รับการจัดการโดยไฮเบอร์เนตและเป็นแคชทั่วทั้งธุรกรรม เมื่อโปรแกรมเรียกเมธอดเซสชัน load () วิธีรับ () วิธีการบันทึก () เมธอด sadeorupdate () เมธอดอัพเดท () หรือวิธีการสืบค้นอินเตอร์เฟสไฮเบอร์เนตจะแคชวัตถุเอนทิตี เมื่อวัตถุเอนทิตีถูกสืบค้นผ่านวิธีการโหลด () หรือรับ () วิธีไฮเบอร์เนตจะทำการสืบค้นในแคชเป็นครั้งแรก เฉพาะเมื่อไม่พบวัตถุเอนทิตีไฮเบอร์เนตจะออกคำสั่ง SQL เพื่อสอบถามในฐานข้อมูลซึ่งจะเป็นการปรับปรุงประสิทธิภาพของการใช้งานของไฮเบอร์เนต
ตัวอย่างเช่น:
แพ็คเกจ com.xqh.util; นำเข้า org.hibernate.session; นำเข้า com.xqh.model.user; การทดสอบคลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {เซสชัน = null; ลอง {เซสชัน = hibernateutil.getSession (); // รับ sessionssion.beginTransaction (); // เปิดใช้งาน Transaction System.out.println ("คำถามแรก:"); user user = (ผู้ใช้) เซสชัน (user.class, จำนวนเต็มใหม่ (1)); system.out.println ("ชื่อผู้ใช้:" + user.getName ()); System.out.println ("การสืบค้นที่สอง:"); ผู้ใช้ผู้ใช้ 1 = (ผู้ใช้) เซสชัน user1.getName ()); session.getTransaction (). commit ();} catch (ข้อยกเว้น e) {e.printstacktrace (); // ข้อผิดพลาดจะย้อนกลับการทำธุรกรรมเซสชัน GetTransaction (). relback ();}} {// ปิดวัตถุเซสชันเมื่อโปรแกรมตรวจสอบวัตถุผู้ใช้เป็นครั้งแรกผ่านวิธี Get () Hibernate จะออกคำสั่ง SQL เพื่อสอบถาม ในเวลานี้ Hibernate ดำเนินการแคชระดับแรกบนวัตถุผู้ใช้ เมื่อสอบถามผ่านวิธี Get () อีกครั้ง Hibernate จะไม่ออกคำสั่ง SQL เนื่องจากชื่อผู้ใช้มีอยู่แล้วในแคชระดับแรก โปรแกรมการรันผลลัพธ์:
แบบสอบถามแรก: hibernate: selectUser0_.id เป็น id0_0_, user0_.name เป็น name0_0_, user0_.sex เป็น sex0_0_ fromtb_user_info user0_ whereuser0_.id =?
หมายเหตุ: วงจรชีวิตของแคชระดับแรกสอดคล้องกับเซสชันและไม่ได้แชร์ระหว่างเซสชัน ในช่วงที่แตกต่างกันวัตถุเอนทิตีที่แคชในช่วงอื่นไม่สามารถรับได้
แคชระดับ 2:
แคชระดับที่สองเป็นแคชระดับเซสชัน factory และวงจรชีวิตของมันสอดคล้องกับ sessionfactory แคชทุติยภูมิสามารถใช้ร่วมกันระหว่างหลายเซสชันและเป็นแคชทั่วทั้งกระบวนการหรือทั่วทั้งคลัสเตอร์
แคชระดับ 2 เป็นปลั๊กอินแคชที่สามารถเสียบได้และการใช้งานนั้นต้องการการสนับสนุนผลิตภัณฑ์แคชของบุคคลที่สาม ในเฟรมเวิร์กไฮเบอร์เนตนโยบายการใช้งานของแคชทุติยภูมิได้รับการกำหนดค่าผ่านไฟล์การกำหนดค่าไฮเบอร์เนต
1. เพิ่มไฟล์การกำหนดค่าแคช ehcache.xml
<ehcache> <! - ตั้งค่าเส้นทางไปยังไดเรกทอรีที่มีการสร้างไฟล์แคช. data ถ้าเส้นทางเป็นคุณสมบัติระบบ Java มันจะถูกแทนที่ค่า BYITS ใน VM. คุณสมบัติต่อไปนี้จะถูกแปล: user.home - Home Directoryuser.dir ของผู้ใช้ path = "java.io.tmpdir"/> <!-การกำหนดค่าแคชเริ่มต้น สิ่งเหล่านี้จะนำไปใช้กับแคชที่สร้างขึ้นอย่างเป็นโปรแกรมผ่าน cachemanager คุณลักษณะต่อไปนี้จำเป็นสำหรับ defaultCache: MaxinMemory - ตั้งค่าจำนวนสูงสุดของวัตถุที่จะถูกสร้างขึ้นใน MemoryEnternal หรือไม่ หากนิรันดร์การหมดเวลาจะถูกละเว้นและ elementis ไม่เคยหมดอายุ timetoidleseconds - ตั้งเวลาที่จะไม่ได้ใช้งานสำหรับองค์ประกอบก่อนที่มันจะหมดอายุ ใช้เฉพาะถ้าองค์ประกอบไม่ใช่นิรันดร์ เวลาว่างคือตอนนี้ - Timetimetoliveseconds ที่เข้าถึงได้ล่าสุด - ตั้งเวลาในการใช้ชีวิตสำหรับองค์ประกอบก่อนที่จะหมดอายุ ใช้เฉพาะถ้าองค์ประกอบไม่ใช่นิรันดร์ TTL คือตอนนี้-การสร้าง TimeOverFlowTodisk-ตั้งค่าว่าองค์ประกอบสามารถล้นไปยังดิสก์เมื่อ cachehas ในหน่วยความจำถึงขีด จำกัด maxinmemory-> <defaultCacheMaxElementsInMemory = "10,000" Eternal = "False" Timetoidleseconds = "120 แคช เพิ่มการตั้งค่าการกำหนดค่าแคชของคุณที่นี่หากคุณไม่มีการกำหนดค่าสำหรับแคชของคุณคำเตือนจะออกเมื่อผู้ใช้งานเริ่มต้นแอตทริบิวต์ต่อไปนี้เป็นสิ่งจำเป็นสำหรับ defaultCache: ชื่อ - ตั้งชื่อแคช สิ่งนี้ใช้เพื่อระบุแคช มันจะต้องไม่ซ้ำกัน MaxInMemory - ตั้งค่าจำนวนสูงสุดของวัตถุที่จะถูกสร้างขึ้นใน MemoryEnternal - ตั้งค่าว่าองค์ประกอบเป็นนิรันดร์หรือไม่ หากนิรันดร์การหมดเวลาจะถูกละเว้นและ elementis ไม่เคยหมดอายุ timetoidleseconds - ตั้งเวลาที่จะไม่ได้ใช้งานสำหรับองค์ประกอบก่อนที่มันจะหมดอายุ ใช้เฉพาะถ้าองค์ประกอบไม่ใช่นิรันดร์ เวลาว่างคือตอนนี้ - Timetimetoliveseconds ที่เข้าถึงได้ล่าสุด - ตั้งเวลาในการใช้ชีวิตสำหรับองค์ประกอบก่อนที่จะหมดอายุ ใช้เฉพาะถ้าองค์ประกอบไม่ใช่นิรันดร์ TTL คือตอนนี้-การสร้าง TimeOverflowTodisk-ตั้งค่าว่าองค์ประกอบสามารถล้นไปยังดิสก์เมื่อ cachehas ในหน่วยความจำถึงขีด จำกัด maxinmemory-> <!-ตัวอย่างแคชตัวอย่างที่ชื่อ SampleCache1 ไปยังแคช TheDisk ซึ่งในการกำหนดค่านี้จะไปที่ใดก็ตามที่ java.io.tmp ถูกกำหนดไว้ในระบบของคุณ ในระบบ Linux มาตรฐานนี้จะเป็น /tmp "-> <cache name =" sampleCache1 "maxElementsInMemory =" 10,000 "นิรันดร์ =" เท็จ "timetoidleseconds =" 300 "timetoliveseconds =" 600 " ไม่หมดอายุ
2. ตั้งค่าไฟล์การกำหนดค่าไฮเบอร์เนต
<!-เปิดใช้งานแคชระดับ 2-> <property name = "hibernate.cache.use_second_level_cache"> true </property> <!-ระบุผู้ให้บริการผลิตภัณฑ์แคช-> <property name = "hibernate.cache.provider_class" usage = "อ่านอย่างเดียว"> </scare-cache>
ตัวอย่าง:
แพ็คเกจ com.xqh.util; นำเข้า org.hibernate.session; นำเข้า com.xqh.model.user; การทดสอบคลาสสาธารณะ {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {เซสชัน = null; // First SessionTry {session = hibernateutil.getSession (); session.beginTransaction (); system.out.println ("คำถามแรก:"); ผู้ใช้ผู้ใช้ = (ผู้ใช้) เซสชัน (user.class, 1); system.out.println ("ชื่อผู้ใช้ {E.PrintStackTrace (); // ข้อผิดพลาดจะย้อนกลับการทำธุรกรรม Session.getTransAction (). ย้อนกลับ ();} ในที่สุด {// ปิดวัตถุเซสชัน HiberNateUtil.Closesession (เซสชัน);} ลอง {เซสชัน = hibernateUtil.getSession (); // เปิดใช้งาน cache session.beginTransaction (); system.out.println ("คำถามที่สอง:"); ผู้ใช้ผู้ใช้ = (ผู้ใช้) เซสชัน. get (user.class, 1); system.out.println ("ชื่อผู้ใช้:" user.getName (); เซสชันการทำธุรกรรม GetTransaction (). การย้อนกลับ ();} ในที่สุด {// ปิดวัตถุเซสชัน hibernateutil.losesession (เซสชัน);}}}}แคชทุติยภูมิถูกแชร์ระหว่างเซสชันดังนั้นวัตถุเดียวกันสามารถโหลดได้ในเซสชันที่แตกต่างกัน Hibernate จะออกคำสั่ง SQL เพียงคำเดียวเท่านั้น เมื่อวัตถุถูกโหลดเป็นครั้งที่สองไฮเบอร์เนตจะได้รับวัตถุนี้จากแคช
ผลลัพธ์ของโปรแกรม:
แบบสอบถามแรก: hibernate: selectUser0_.id เป็น id0_0_, user0_.name เป็น name0_0_, user0_.sex เป็น sex0_0_ fromtb_user_info user0_ whereuser0_.id =?
สำหรับแคช L2 สามารถใช้ข้อมูลหรือข้อมูลอ้างอิงได้ไม่บ่อยนักและสามารถใช้งานได้และประสิทธิภาพจะได้รับการปรับปรุงอย่างมีนัยสำคัญในเวลานี้ อย่างไรก็ตามหากใช้ข้อมูลที่เปลี่ยนแปลงบ่อยครั้งสำหรับแคช L2 ประสิทธิภาพจะทำให้เกิดปัญหาบางอย่าง
ฉันหวังว่าคำอธิบายในบทความนี้จะเป็นประโยชน์กับการเขียนโปรแกรม Java ของทุกคนตามกรอบการทำงานของไฮเบอร์เนต