แคชไฮเบอร์เนต
การแคชเป็นเรื่องเกี่ยวกับการเพิ่มประสิทธิภาพประสิทธิภาพของแอปพลิเคชันและอยู่ระหว่างแอปพลิเคชันและฐานข้อมูลเพื่อหลีกเลี่ยงการเข้าถึงฐานข้อมูลที่หลากหลายและอนุญาตให้แอปพลิเคชันที่สำคัญต่อประสิทธิภาพทำงานได้ดีขึ้น
การแคชเป็นสิ่งสำคัญสำหรับไฮเบอร์เนตและใช้รูปแบบการแคชหลายระดับที่อธิบายไว้ด้านล่าง:
แคชระดับ 1:
แคชระดับแรกคือแคชเซสชันซึ่งเป็นแคชบังคับและคำขอทั้งหมดผ่านมันจะต้องผ่าน วัตถุเซสชันจะถูกขับเคลื่อนโดยวัตถุอย่างต่อเนื่องก่อนที่จะส่งไปยังฐานข้อมูล
หากมีการอัปเดตหลายครั้งพยายามที่จะชะลอการอัปเดตให้นานที่สุดเท่าที่จะเป็นไปได้เพื่อลดจำนวนการอัปเดตคำสั่ง SQL ที่ออกให้ หากคุณปิดเซสชันวัตถุที่แคชทั้งหมดจะหายไปไม่ว่าจะถาวรหรืออัปเดตในฐานข้อมูล
แคชระดับ 2:
แคชระดับ 2 เป็นตัวเลือกและแคชระดับ 1 ที่จะค้นหาก่อนที่จะพยายามค้นหาแคชระดับ 2 ของวัตถุ แคชระดับที่สองสามารถกำหนดค่าได้ตามระดับและต่อหมวดหมู่ส่วนใหญ่รับผิดชอบในการแคชวัตถุในเซสชั่น
แคชของบุคคลที่สามใด ๆ สามารถใช้ไฮเบอร์เนตได้ อินเทอร์เฟซ org.hibernate.cache.cacheprovider ให้และจำเป็นต้องใช้การใช้งานแคชสำหรับการจัดหาไฮเบอร์เนต
แคชระดับสอบถาม:
ไฮเบอร์เนตยังใช้การรวมตัวของชุดสืบค้นชุดและแคชระดับ 2 อย่างแน่นหนา
นี่เป็นคุณสมบัติเสริมที่ต้องใช้แคชทางกายภาพเพิ่มเติมสองตัวเพื่อบันทึกผลลัพธ์การสืบค้นแคชและภูมิภาคเมื่อตารางได้รับการอัปเดตล่าสุด สิ่งนี้มีประโยชน์มากสำหรับการสืบค้นที่มักจะทำงานด้วยพารามิเตอร์เดียวกัน
แคชระดับ 2:
Hibernate ใช้แคชระดับ 1 โดยค่าเริ่มต้นคุณไม่ได้ทำอะไรกับแคชระดับ 1 ไปตรงไปที่แคชระดับสองเสริม ไม่ใช่ทุกคลาสที่ได้รับประโยชน์จากการแคชดังนั้นจึงเป็นสิ่งสำคัญที่จะปิดการใช้งานแคชระดับ 2
แคชระดับไฮเบอร์เนตระดับ 2 ถูกตั้งค่าเป็นสองขั้นตอน ก่อนอื่นคุณต้องตัดสินใจว่าจะใช้กลยุทธ์การพร้อมกันใด หลังจากนี้คุณสามารถกำหนดค่าการหมดอายุของแคชและใช้แคชเพื่อให้แอตทริบิวต์แคชทางกายภาพ
กลยุทธ์พร้อมกัน:
นโยบายพร้อมกันเป็นสื่อกลางที่รับผิดชอบในการจัดเก็บรายการข้อมูลในแคชและดึงพวกเขาออกจากแคช หากคุณต้องการเปิดใช้งานการแคชระดับ 2 คุณจะต้องตัดสินใจว่าจะใช้นโยบายพร้อมกันของแคชใดสำหรับแต่ละคลาสและการรวบรวมแบบถาวร
การทำธุรกรรม: การใช้กลยุทธ์นี้เพื่ออ่านข้อมูลเป็นหลักเพื่อป้องกันการทำธุรกรรมพร้อมกันของข้อมูลที่ล้าสมัยเป็นสิ่งสำคัญในกรณีการอัปเดตที่หายาก
Read-Write: ใช้กลยุทธ์นี้อีกครั้งการอ่านข้อมูลหลักมีความสำคัญอย่างยิ่งต่อการป้องกันการทำธุรกรรมพร้อมกันจากข้อมูลเก่าในกรณีที่หายากของการอัปเดต
Nonstrict-Read-Write: กลยุทธ์นี้ไม่รับประกันความสอดคล้องระหว่างแคชและฐานข้อมูล ด้วยกลยุทธ์นี้คีย์คือไม่ให้ความสนใจหากข้อมูลไม่ค่อยมีการเปลี่ยนแปลงและความเป็นไปได้ของข้อมูลเก่าจะต้องค้าง
อ่านอย่างเดียว: นโยบายพร้อมกันเหมาะสำหรับข้อมูลและจะไม่เปลี่ยนแปลง ข้อมูลที่ใช้สำหรับการอ้างอิงเท่านั้น
หากเราต้องการใช้แคชระดับที่สองเป็นคลาสพนักงานของเราเรามาเพิ่มองค์ประกอบการแมปที่จำเป็นในการบอกให้ Hibernate ใช้นโยบายแคชที่อ่านได้และสามารถเขียนได้สำหรับอินสแตนซ์ของพนักงาน
<? XML เวอร์ชัน = "1.0" การเข้ารหัส = "UTF-8"?> <! Doctype Hibernate-Mapping สาธารณะ "-// hibernate/hibernate mapping dtd // en" "http://www.hibernate.org/dtd/hibernate-mapping-3 table = "พนักงาน"> <meta attribute = "Class-Description"> คลาสนี้มีรายละเอียดของพนักงาน </meta> <cache usage = "read-write"/> <id name = "id" type = "int" คอลัมน์ = "id"> <generator/> </id> <property name = "firstName" คอลัมน์ = "first_name" type = "String"/> <property name = "LastName" </class> </hibernate-mapping>
คุณสมบัติการใช้งาน = "Read-Write" บอกให้ Hibernate ใช้แคชที่กำหนดโดยนโยบายการทำงานพร้อมกันของการอ่าน-เขียน
ผู้ให้บริการแคช:
หลังจากพิจารณานโยบายพร้อมกันของคลาสผู้สมัครแคชของคุณขั้นตอนต่อไปคือการเลือกผู้ให้บริการแคช กองกำลังไฮเบอร์เนตเลือกแคชเพื่อให้บริการแอปพลิเคชันทั้งหมด
แคชที่ให้ไว้ในไฟล์กำหนดค่า hibernate.cfg.xml ที่ระบุ เลือก Ehcache เป็นผู้ให้บริการแคชระดับที่สอง:
<? XML เวอร์ชัน = "1.0" การเข้ารหัส = "UTF-8"?> <! Doctype Hibernate-Configuration System "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> org.hibernate.dialect.mysqldialect </คุณสมบัติ> <property name = "hibernate.connection.driver_class"> com.mysql.jdbc.driver </คุณสมบัติ> <! name = "hibernate.connection.username"> root </property> <property name = "hibernate.connection.password"> root123 </คุณสมบัติ> <property name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider Resource = "Employee.hbm.xml"/> </session-factory> <//hibernate-configuration>
ตอนนี้คุณต้องระบุคุณสมบัติของพื้นที่แคช Ehcache มีไฟล์การกำหนดค่าของตัวเอง ehcache.xml ในแอปพลิเคชันใน classpath ใน ehcache.xml การกำหนดค่าแคชคลาสพนักงานอาจมีลักษณะเช่นนี้:
<diskstore path = "java.io.tmpdir"/> <defaultCacheMaxElementsInMemory = "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 ให้ Hibernate สร้างแคชที่ต้องการในหน่วยความจำเพื่อบันทึกชุดคิวรีและตัวระบุ
ถัดไปการใช้แคชแบบสอบถามคุณสามารถใช้วิธี setCacheable (บูลีน) ของคลาสการสืบค้น ตัวอย่างเช่น:
เซสชั่นเซสชัน = SessionFactory.opensession (); Query Query = session.createquery ("จากพนักงาน"); query.setCacheable (จริง); list users = query.list (); sessionfactory.losesession ();Hibernate ยังรองรับการสนับสนุนแคชที่ละเอียดมากผ่านแนวคิดของพื้นที่แคช แคชเป็นส่วนหนึ่งของแคชที่ได้รับชื่อ
เซสชั่น = sessionfactory.opensession (); Query Query = session.createquery ("จากพนักงาน"); query.setCacheable (จริง); query.setCacheregion ("พนักงาน"); ผู้ใช้รายการ = query.list (); sessionFactory.losesession ();รหัสนี้ใช้วิธีการบอก Hibernate เพื่อจัดเก็บและค้นหาคำถามเกี่ยวกับพนักงานในแคช
Hibernate Native SQL
คุณสามารถใช้ SQL ดั้งเดิมเพื่อแสดงการสืบค้นฐานข้อมูล หากคุณต้องการใช้ฟังก์ชั่นเฉพาะฐานข้อมูลเช่นการสืบค้นหรือเชื่อมต่อคำหลักใน Oracle Hibernate3.x อนุญาตให้ใช้คำสั่ง SQL ที่เขียนด้วยลายมือรวมถึงขั้นตอนที่เก็บไว้การสร้างทั้งหมดอัปเดตลบและโหลดการดำเนินการ
แอปพลิเคชันจะสร้างแบบสอบถาม SQL แบบดั้งเดิม (บนอินเทอร์เฟซเซสชัน) จากเมธอดเซสชัน createsqlQuery ():
SQLQuery Public CreateSqlQuery (String sqlstring) พ่น HibernateException
เมื่อผ่านการสืบค้น SQL ไปยังเมธอด createsqlQuery () คุณสามารถใช้วิธีการเสริม () ที่เกี่ยวข้องกับเอนทิตีไฮเบอร์เนตที่มีอยู่หรือผลลัพธ์สเกลาร์โดยใช้วิธีการเสริม (), addjoin () และ addscalar ()
สการ์คิวรี:
แบบสอบถาม SQL ขั้นพื้นฐานที่สุดคือการรับรายการสเกลาร์ (ค่าตัวเลข) จากหนึ่งตารางขึ้นไป นี่คือค่าของไวยากรณ์โดยใช้ SQL Scalars ดั้งเดิม:
String sql = "เลือก first_name, เงินเดือนจากพนักงาน"; sqlQuery query = session.createsqlQuery (SQL); query.setResultTransformer (Criteria.Alias_To_ENTITY_MAP); รายการผลลัพธ์ = query.list ();
คำถามเอนทิตี:
แบบสอบถามข้างต้นส่งคืนค่าสเกลาร์ทั้งหมดนั่นคือข้อมูล "เปลือยกาย" ที่ส่งคืนจากชุดผลลัพธ์ ต่อไปนี้เป็นไวยากรณ์เพื่อให้ได้วัตถุเอนทิตีโดยรวมจากแบบสอบถาม SQL ดั้งเดิมผ่านวิธี Addentity ()
String SQL = "SELECT * จาก Employee"; SQLQuery Query = Session.createsqlQuery (SQL); query.addentity (Employee.Class); รายการผลลัพธ์ = query.list ();
ชื่อ SQL Query:
ต่อไปนี้เป็นไวยากรณ์เพื่อรับวัตถุเอนทิตีจากแบบสอบถาม SQL ดั้งเดิมและใช้ชื่อ SQL Queries ผ่านวิธี Addentity ()
String SQL = "SELECT * จากพนักงานโดยที่ ID =: Employee_id"; SQLQuery Query = session.createsqlQuery (SQL); query.addentity (Employee.Class); query.setParameter ("ExplueEE_ID", 10); ตัวอย่าง SQL ดั้งเดิม:
พิจารณาคลาส Pojo ต่อไปนี้:
พนักงานชั้นเรียนสาธารณะ {ID INT ส่วนตัว; สตริงส่วนตัวชื่อแรก; สตริงส่วนตัวนามสกุล; เงินเดือนส่วนตัว พนักงานสาธารณะ () {} พนักงานสาธารณะ (สตริง fname, สตริง lname, เงินเดือน int) {this.firstname = fname; this.lastName = lName; this.salary = เงินเดือน; } สาธารณะ int getId () {return id; } โมฆะสาธารณะ setId (int id) {this.id = id; } สตริงสาธารณะ getFirstName () {return firstName; } โมฆะสาธารณะ setFirstName (สตริง first_name) {this.firstName = first_name; } สตริงสาธารณะ getLaStName () {return lastName; } โมฆะสาธารณะ setLastName (สตริง last_name) {this.lastName = last_name; } public int getalary () {คืนเงินเดือน; } โมฆะสาธารณะ setSalary (เงินเดือน int) {this.salary = เงินเดือน; -มาสร้างตารางพนักงานต่อไปนี้เพื่อจัดเก็บวัตถุพนักงาน:
สร้างพนักงานตาราง (ID int ไม่ใช่ null auto_increment, first_name varchar (20) ค่าเริ่มต้น null, last_name varchar (20) ค่าเริ่มต้น null, เงินเดือน int เริ่มต้น null, คีย์หลัก (id));
ต่อไปนี้จะถูกแมปไฟล์
<? XML เวอร์ชัน = "1.0" การเข้ารหัส = "UTF-8"?> <! Doctype Hibernate-Mapping สาธารณะ "-// hibernate/hibernate mapping dtd // en" "http://www.hibernate.org/dtd/hibernate-mapping-3 table = "พนักงาน"> <meta attribute = "Class-Description"> คลาสนี้มีรายละเอียดของพนักงาน </meta> <id name = "id" type = "int" คอลัมน์ = "id"> <generator/> </id> <property name = "FirstName" คอลัมน์ = "First_name" type = "String"/> <property name = "LastName" Column = "Last_name" Type = "String"/> <
ในที่สุดเราจะสร้างวิธีการหลัก () ของคลาสแอปพลิเคชันเพื่อเรียกใช้และเราจะใช้แอปพลิเคชัน SQL แบบสอบถามดั้งเดิม:
นำเข้า Java.util.*; นำเข้า org.hibernate.HibernateException; นำเข้า org.hibernate.session; นำเข้า org.hibernate.transaction; นำเข้า org.hibernate.sessionfactory; นำเข้า org.hibernate.sqlQuery นำเข้า org.hibernate.criteria; นำเข้า org.hibernate.hibernate; นำเข้า org.hibernate.cfg.configuration โมฆะคงที่สาธารณะหลัก (สตริง [] args) {ลอง {โรงงาน = การกำหนดค่าใหม่ (). configure (). buildSessionFactory (); } catch (throwable ex) {system.err.println ("ล้มเหลวในการสร้างวัตถุ SessionFactory" + ex); โยนข้อยกเว้นใหม่ IniniNitializerError (EX); } managemployee me = new Managemployee (); / * เพิ่มระเบียนพนักงานไม่กี่รายในฐานข้อมูล */ จำนวนเต็ม EMPID1 = Me.addemployee ("Zara", "Ali", 2000); จำนวนเต็ม Empid2 = me.addemployee ("Daisy", "Das", 5000); จำนวนเต็ม empid3 = me.addemployee ("John", "Paul", 5000); จำนวนเต็ม empid4 = me.addemployee ("mohd", "yasee", 3000); / * แสดงรายการพนักงานและเงินเดือนของพวกเขาโดยใช้สการ์แบบสอบถาม */ me.listemployeesscalar (); / * รายการข้อมูลพนักงานที่สมบูรณ์โดยใช้แบบสอบถามเอนทิตี */ me.listemployeesentity (); } / * วิธีการสร้างพนักงานในฐานข้อมูล * / addemployee จำนวนเต็มสาธารณะ (สตริง fname, สตริง lname, เงินเดือน int) {เซสชันเซสชัน = factory.opensession (); ธุรกรรม tx = null; จำนวนเต็ม EmployeeId = null; ลอง {tx = session.beginTransaction (); พนักงานพนักงานพนักงาน = พนักงานใหม่ (fname, lname, เงินเดือน); EmployeeId = (จำนวนเต็ม) เซสชั่น SAVE (พนักงาน); tx.commit (); } catch (hibernateException e) {ถ้า (tx! = null) tx.rollback (); E.PrintStackTrace (); } ในที่สุด {session.close (); } return EmployeeId; } / * วิธีการอ่านพนักงานทั้งหมดโดยใช้สการ์แบบสอบถาม * / โมฆะสาธารณะ ListEmployeEscalar () {เซสชัน session = factory.opensession (); ธุรกรรม tx = null; ลอง {tx = session.beginTransaction (); String SQL = "เลือก First_name, เงินเดือนจากพนักงาน"; sqlQuery query = session.createsqlQuery (SQL); query.setResultTransformer (criteria.alias_to_entity_map); รายการข้อมูล = query.list (); สำหรับ (วัตถุวัตถุ: ข้อมูล) {map row = (แผนที่) วัตถุ; System.out.print ("ชื่อแรก:" + row.get ("first_name")); System.out.println (", เงินเดือน:" + row.get ("เงินเดือน")); } tx.Commit (); } catch (hibernateException e) {ถ้า (tx! = null) tx.rollback (); E.PrintStackTrace (); } ในที่สุด {session.close (); }} / * วิธีการอ่านพนักงานทั้งหมดโดยใช้การสืบค้นเอนทิตี * / โมฆะสาธารณะ ListemployeEsentity () {เซสชัน session = factory.opensession (); ธุรกรรม tx = null; ลอง {tx = session.beginTransaction (); String SQL = "SELECT * จากพนักงาน"; sqlQuery query = session.createsqlQuery (SQL); query.addentity (Employee.class); รายการพนักงาน = query.list (); สำหรับ (iterator iterator = พนักงาน. titerator (); iterator.hasnext ();) {พนักงานพนักงาน = (พนักงาน) iterator.next (); System.out.print ("ชื่อแรก:" + Employee.getFirstName ()); System.out.print ("นามสกุล:" + Employee.getLastName ()); System.out.println ("เงินเดือน:" + Employee.getSalary ()); } tx.Commit (); } catch (hibernateException e) {ถ้า (tx! = null) tx.rollback (); E.PrintStackTrace (); } ในที่สุด {session.close (); - รวบรวมและดำเนินการ:
นี่คือขั้นตอนในการรวบรวมและเรียกใช้แอปพลิเคชันด้านบน โปรดตรวจสอบให้แน่ใจว่ามีการตั้งค่าเส้นทางและ classpath อย่างเหมาะสมก่อนที่จะรวบรวมและดำเนินการ
เรียกใช้ไฟล์ไบนารี managemployee เพื่อเรียกใช้โปรแกรม
ผลลัพธ์ต่อไปนี้จะได้รับและบันทึกจะถูกสร้างขึ้นในตารางพนักงาน
$ java managemployee
...... ข้อความบันทึกต่าง ๆ จะแสดงที่นี่ ......... ชื่อแรก: Zara, เงินเดือน: 2000 ชื่อชื่อ: Daisy, เงินเดือน: 5000 ชื่อ First: John, เงินเดือน: 5000 First Name: Mohd, เงินเดือน: 3000 First Name: Zara ชื่อสุดท้าย: Ali เงินเดือน: ชื่อชื่อ: Daisy Salary นามสกุล Mohd: Yasee Salary: 3000
หากคุณตรวจสอบตารางพนักงานควรบันทึกว่ามี:
mysql> เลือก * จากพนักงาน;
- -