1. วงจรชีวิตของวัตถุถาวร
หลังจากแอปพลิเคชันใช้เฟรมเวิร์กไฮเบอร์เนตวัตถุถาวรที่สร้างขึ้นโดยแอปพลิเคชันจะต้องผ่านชุดวงจรชีวิตที่สมบูรณ์เพื่อให้การดำเนินการฐานข้อมูลเสร็จสิ้นซึ่งทั้งสามสถานะหลักคือการคงอยู่ชั่วคราวและแยกออก การเปลี่ยนผ่านของทั้งสามสถานะสามารถควบคุมได้ในแอปพลิเคชันดังแสดงในรูปด้านล่าง:
เพื่อให้เข้าใจสถานะเหล่านี้อย่างชัดเจนนี่คือตัวอย่างที่จะดูความแตกต่างระหว่างวัตถุในสถานะเหล่านี้ รหัสต่อไปนี้ในรัฐมีดังนี้:
(1) สร้างชุดประกอบ Hibernate_Session และเพิ่มแพ็คเกจ JAR ที่สอดคล้องกัน
(2) กำหนดค่าไฮเบอร์เนตเพิ่มคลาสผู้ใช้เอนทิตีที่สอดคล้องกันและไฟล์การแมปและกำหนดค่าการเชื่อมต่อฐานข้อมูลที่เกี่ยวข้อง
ไฟล์การแมปไฟล์คลาสผู้ใช้รหัส user.hbm.xml รหัส:
<? xml เวอร์ชัน = "1.0"?> <! Doctype hibernate-mapping สาธารณะ "-// hibernate/hibernate mapping dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" 3.4.0.cr1-> <hibernate-mapping> <class name = "com.hibernate.user"> <id name = "id"> <generator/> </id> <name property = "name"/> <property name = "password"/> <property name = "createTime"/>
รหัสการกำหนดค่าการเชื่อมต่อฐานข้อมูลไฮเบอร์เนต:
<? XML เวอร์ชัน = "1.0" การเข้ารหัส = "UTF-8"?> <! doctype hibernate-configuration สาธารณะ "-// hibernate/hibernate การกำหนดค่า dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-configuration-3 <session-factory> <property name = "hibernate.connection.driver_class"> com.mysql.jdbc.driver </คุณสมบัติ> <property name = "hibernate.connection.url"> jdbc: mysql: // localhost: 3306/hibernate_session <property name = "hibernate.connection.password"> ab12 </property> <!-ภาษาถิ่น: ภาษาถิ่น, API พื้นฐานที่ห่อหุ้ม, คล้ายกับรันไทม์, แปลงฐานข้อมูลเป็นภาษาที่เกี่ยวข้องในการกำหนดค่า-> <property name = "hibernate.dialect Resource = "com/hibernate/user.hbm.xml"/> </session-factory> </hibernate-configuration>
(3) เพิ่มคลาสสาธารณะของสมาชิกแบบคงที่ SessionFactory เพื่อสร้าง SessionFactory และวัตถุเซสชัน
แพ็คเกจ com.hibernate; นำเข้า org.hibernate.session; นำเข้า org.hibernate.sessionfactory; นำเข้า org.hibernate.cfg.configuration; เซสชั่นชั้นเรียนสาธารณะ {โรงงาน SessionFactory ส่วนตัว // ประกาศตัวแปรท้องถิ่นแบบคงที่ SessionFactory ฐานข้อมูล Database Static {ลอง {// สร้างและรับไฟล์การกำหนดค่าสำหรับฐานข้อมูลการกำหนดค่าและรับ hibernate.cfg.xml การกำหนดค่า cfg = การกำหนดค่าใหม่ (). configure (); โรงงาน = cfg.buildsessionFactory (); // สร้างภาพฐานข้อมูล} catch (Exception e) {E.printStackTrace (); // พิมพ์ข้อความแสดงข้อผิดพลาด}} เซสชันคงที่สาธารณะ getSession () {return factory.opensession (); // ส่งคืนวัตถุเซสชันที่สร้างขึ้น} สาธารณะ sessionfactory getSessionfactory () {return Factory; // ส่งคืน SessionFactory ที่สอดคล้องกัน} // ปิดออบเจ็กต์เซสชันโมฆะสาธารณะคงที่การปิด (เซสชันเซสชัน) {ถ้า (เซสชัน! = null) {ถ้า (session.isopen ()) {session.close (); -(4) เพิ่มโฟลเดอร์ต้นทางและเพิ่มแพ็คเกจชื่อ com.hibernate ในโฟลเดอร์และเพิ่มไฟล์คลาสชื่อ SessionTest ลงในแพ็คเกจ
แพ็คเกจ com.hibernate; นำเข้า java.util.date; นำเข้า junit.framework.testcase; นำเข้า org.hibernate.session; นำเข้า org.hibernate.transaction; SessionTest ระดับสาธารณะขยาย TestCase {} 2. วิธีการแปลงสถานะ
1. วัตถุเข้าสู่สถานะถาวรโดยตรง
1.1 รับวิธี
รับแถวข้อมูลจากฐานข้อมูลและซิงโครไนซ์ข้อมูลลงในวัตถุที่สร้างขึ้น วิธีนี้ส่งคืนวัตถุวัตถุและส่งคืนค่า null หากไม่พบเนื้อหา ตัวอย่างต่อไปนี้ใช้เมธอดเซสชันเพื่อรับวัตถุและแปลงวัตถุเป็นอินสแตนซ์
โมฆะสาธารณะ TestGet1 () {เซสชันเซสชัน = null; ธุรกรรม tx = null; ลอง {session = hibernateutils.getSession (); // เปิดธุรกรรม tx = session.beginTransaction (); // วัตถุที่โหลดโดย GET เป็นวัตถุถาวร // ดำเนินการ Get to ออกคำสั่ง Query ทันทีและหากไม่มีอยู่มันจะส่งคืนผู้ใช้ NULL ผู้ใช้ null = (ผู้ใช้) เซสชัน (user.class, "FF80808145BC28CC0145BC28CE020002"); System.out.println (user.getName ()); // สถานะถาวร // วัตถุที่มีการเปลี่ยนแปลงสถานะถาวรเมื่อคุณสมบัติของวัตถุเปลี่ยนไป // hibernate จะซิงโครไนซ์ user.setName ("zhao liu"); session.getTransaction (). commit (); } catch (exception e) {e.printstacktrace (); if (tx! = null) {tx.rollback (); }} ในที่สุด {hibernateutils.closesession (เซสชัน); - ตั้งค่าเบรกพอยต์เพื่อรับวัตถุผู้ใช้
ได้รับวัตถุนี้และได้รับวัตถุผู้ใช้หลังจากการหล่อ วิธีการตั้งชื่อจะถูกเพิ่มลงในโปรแกรมซึ่งหมายความว่าชื่อในฐานข้อมูลจะได้รับการอัปเดต หลังจากการดำเนินการเสร็จสิ้นฐานข้อมูลจะถูกตรวจสอบดังที่แสดงในรูปด้านล่างเพื่ออัปเดตผลลัพธ์
1.2 วิธีการโหลด
ฟังก์ชั่นนั้นคล้ายกับวิธี GET และยังได้รับข้อมูลจากฐานข้อมูลและซิงโครไนซ์ลงในวัตถุ วิธีนี้รองรับการทำงานที่ขี้เกียจ มันส่งคืนวัตถุวัตถุที่ถาวรหรือพร็อกซีดังนั้นจึงจำเป็นต้องได้รับการแปลง
โมฆะสาธารณะ testload1 () {เซสชันเซสชัน = null; ลอง {session = hibernateutils.getSession (); // คำสั่ง Query จะไม่ถูกตรวจสอบทันทีเนื่องจากโหลดรองรับ LAZY (โหลดล่าช้า/LAZY LOAD) // จะสอนอะไรขี้เกียจ? เฉพาะเมื่อมีการใช้วัตถุนี้อย่างแท้จริงและสร้างขึ้นมาคำสั่งการสืบค้นจะถูกออกสำหรับไฮเบอร์เนต ส่วนใหญ่เป็นการปรับปรุงประสิทธิภาพ ขี้เกียจเป็นคุณสมบัติที่สำคัญมากในไฮเบอร์เนต Lazy of Hibernate ถูกนำไปใช้อย่างไร? ดำเนินการโดยวัตถุพร็อกซี วัตถุพร็อกซีส่วนใหญ่ใช้ // สร้างโดยไลบรารี CGLIB แทนพร็อกซีแบบไดนามิกของ JDK เนื่องจากพร็อกซีแบบไดนามิกของ JDK สามารถสร้างพร็อกซีสำหรับคลาสที่ใช้ข้อแก้ตัวได้ CGLIB สามารถสร้าง // พร็อกซีสำหรับชั้นเรียน มันใช้วิธีการสืบทอดเมธอดผู้ใช้ = (ผู้ใช้) เซสชันโหลด (user.class, "8A1B653745BCC7B50145BCC7B7B7140001"); System.out.println (user.getName ()); // สถานะถาวร // วัตถุที่มีสถานะถาวรเมื่อคุณสมบัติของวัตถุเปลี่ยนไป // hibernate จะซิงโครไนซ์ user.setName ("zhaoliu"); session.getTransaction (). commit (); } catch (exception e) {e.printstacktrace (); } ในที่สุด {hibernateutils.closesession (เซสชัน); - แบบสอบถามเพื่อรับวัตถุผู้ใช้ดังแสดงในรูปด้านล่าง:
การวิเคราะห์ตัวเลขด้านบนวัตถุผู้ใช้ที่ได้รับไม่สมบูรณ์หรือไม่มีวัตถุผู้ใช้ทั่วไป แต่เป็นพร็อกซี มันใช้ CGLIB เพื่อโหลดวัตถุไว้ล่วงหน้าและสร้างขึ้นอย่างแท้จริงเมื่อใช้วัตถุ
1.3 รับ vs load
รับและวิธีการโหลดมีความสำคัญมาก พวกเขามักจะถูกถ่ายในระหว่างการสัมภาษณ์กับไฮเบอร์เนต ต่อไปนี้เป็นการเปรียบเทียบสองรายการต่อไปนี้
ความคล้ายคลึงกัน:
(1) ฟังก์ชั่นเหมือนกันและข้อมูลความสัมพันธ์จะถูกแปลงเป็นวัตถุ
(2) วิธีการใช้งานเหมือนกันและจำเป็นต้องมีความแตกต่างสองประการในพารามิเตอร์:
(1) วิธีการโหลดรองรับการทำงานที่ขี้เกียจโหลดวัตถุไว้ล่วงหน้าและถูกสร้างขึ้นเมื่อใช้เท่านั้น รับการแปลงข้อมูลเชิงสัมพันธ์โดยตรงเป็นวัตถุ
(2) หากไม่มีวัตถุโหลดโหลด ObjectNotFoundException จะถูกโยนลงและหาก GET ไม่ได้รับข้อมูลมันจะส่งคืนค่า NULL
2. สร้างวัตถุเดี่ยวด้วยตนเอง
มีวิธีอื่นในการรับวัตถุ มันแตกต่างจากวิธีการรับและโหลด มันเป็นวิธีการด้วยตนเอง ขั้นแรกวัตถุเป็นเรื่องธรรมดาจากนั้นข้อมูลของวัตถุจะได้รับจากการกำหนด ID วิธีนี้มีดังนี้:
โมฆะสาธารณะ Testuer () {เซสชันเซสชัน = null; ลอง {session = hibernateutils.getSession (); session.beginTransaction (); // สร้างผู้ใช้ ObjectUser เดี่ยวด้วยตนเอง = ผู้ใช้ใหม่ (); user.setId ("8A1B653745BCC7B50145BCC7B7B7140001"); // สถานะถาวร // วัตถุที่มีสถานะถาวรเมื่อคุณสมบัติของวัตถุเปลี่ยนไป // hibernate จะซิงโครไนซ์เซสชั่น getTransaction (). commit () กับฐานข้อมูลเมื่อทำความสะอาดแคช (ตรวจสอบข้อมูลสกปรก); } catch (exception e) {e.printstacktrace (); } ในที่สุด {hibernateutils.closesession (เซสชัน); - ดูแผนภาพผลลัพธ์ที่ได้รับ:
ไดอะแกรมผลการวิเคราะห์ใช้ในรหัสเพื่อตั้งค่าหมายเลข ID สำหรับวัตถุ หลังจากกำหนดหมายเลข ID แล้ววัตถุสามารถทำงานได้ หลังจากส่งธุรกรรมแล้วจะถูกซิงโครไนซ์กับฐานข้อมูลและใช้ข้อกำหนดด้วยตนเองเพื่อระบุข้อมูลวัตถุด้วยตนเอง
2.1 วิธีลบ
ในการลบวัตถุที่ระบุในฐานข้อมูลวัตถุจะต้องแปลงเป็นสถานะถาวรก่อนที่จะลบออก คุณสามารถใช้วิธีการรับโหลดหรือแบบแมนนวลเพื่อระบุวัตถุ วิธีนี้มีดังนี้:
เซสชั่น = hibernateutils.getSession (); session.beginTransaction (); ผู้ใช้ผู้ใช้ = (ผู้ใช้) เซสชันการโหลด (user.class, "8A1B653745BCC6D50145BCC6D67A0001"); // ขอแนะนำให้ใช้วิธีนี้ในการลบโหลดก่อนจากนั้นลบเซสชัน delete (ผู้ใช้);
2.2 อัปเดต
อัปเดตข้อมูลวิธีนี้จะแก้ไขข้อมูลในฐานข้อมูล เมื่อใช้งานจะมีสถานการณ์ในปริมาณซึ่งจะอัปเดตค่าของฟิลด์ที่แน่นอนในฐานข้อมูลหรืออัปเดตทั้งแถวของฐานข้อมูล
2.2.1 อัปเดตค่าฟิลด์
หากคุณต้องการอัปเดตค่าของฟิลด์ที่แน่นอนก่อนที่จะอัปเดตคุณต้องใช้โหลดหรือรับการแปลงวัตถุเป็นรหัสสถานะถาวรดังนี้:
// รับ Session Object Session = hibernateutils.getSession (); // เปิดเซสชันการทำธุรกรรม BEGINTRANSACTION (); // หรือคุณสามารถใช้วิธีอื่นเพื่อเปิดใช้งาน //session.getTransaction (). เริ่มต้น (); // โหลดเพื่อรับวัตถุผู้ใช้ // วิธีการ 1: ใช้วิธีการโหลด // ผู้ใช้ผู้ใช้ = (ผู้ใช้) เซสชัน load (user.class, "8A1B653745BCC7B50145BCC7B7B7140001"); // วิธีที่ 2: รับผู้ใช้ผู้ใช้ด้วยตนเอง = ผู้ใช้ใหม่ (); user.setId ("8A1B653745BCC7B50145BCC7B7B7140001"); // อัปเดตชื่อ user.setName ("Zhangsan"); session.update (ผู้ใช้); session.getTransaction (). commit ();2.2.2 อัปเดตบรรทัดทั้งหมด <br /> หากคุณต้องการอัปเดตข้อมูลของบรรทัดทั้งหมดคุณสามารถแปลงสถานะเป็นสถานะเดี่ยวและระบุค่า id ของวัตถุด้วยตนเอง รหัสมีดังนี้:
// รับ Session Object Session = hibernateutils.getSession (); // เปิดเซสชันการทำธุรกรรม BEGINTRANSACTION (); // หรือสามารถใช้วิธีอื่นเพื่อเปิดใช้งาน //session.getTransaction (). เริ่มต้น (); // รับผู้ใช้ด้วยตนเอง = ผู้ใช้ใหม่ (); user.setId ("8A1B653745BCC7B50145BCC7B7B7140001"); // อัปเดตชื่อ user.setName ("Zhangsan"); session.update (ผู้ใช้); session.getTransaction (). commit (); ดูผลลัพธ์การอัปเดต:
การวิเคราะห์ผลลัพธ์การอัปเดตจริง ๆ แล้วอัพเดทข้อมูลทั้งหมดของฐานข้อมูล มีความไม่แน่นอนมากเกินไปในการดำเนินการอัปเดตนี้และไม่แนะนำให้ใช้
2.3 บันทึกวิธีการ
แทรกข้อมูล เมื่อดำเนินการวิธีการบันทึกคำสั่ง INSERT ฐานข้อมูลจะถูกเรียกให้เพิ่มแถวใหม่ลงในฐานข้อมูล วัตถุที่บันทึกไว้จะถูกแปลงเป็นสถานะถาวร ในสถานะนี้วัตถุสามารถอัปเดตวัตถุอีกครั้งและจะได้รับการอัปเดตไปยังฐานข้อมูลที่มีการเปลี่ยนแปลงเมื่อการทำธุรกรรมถูกส่งในที่สุด ดังนี้:
โมฆะสาธารณะ testSave2 () {เซสชันเซสชัน = null; ธุรกรรม tx = null; ลอง {session = hibernateutils.getSession (); // เปิดธุรกรรม tx = session.beginTransaction (); // ผู้ใช้สถานะชั่วคราวผู้ใช้ = ผู้ใช้ใหม่ (); user.setName ("Zhangsi"); user.setPassword ("123"); user.setCreateTime (วันที่ใหม่ ()); user.setexpiretime (วันที่ใหม่ ()); // สถานะถาวร // วัตถุที่มีการเปลี่ยนแปลงสถานะถาวรเมื่อคุณสมบัติของวัตถุเปลี่ยนไป // hibernate จะซิงโครไนซ์เซสชัน Save (ผู้ใช้); user.setName ("lisi"); tx.commit (); } catch (exception e) {e.printstacktrace (); if (tx! = null) {tx.rollback (); }} ในที่สุด {hibernateutils.closesession (เซสชัน); } // สถานะเดี่ยว} ดูตัวอย่างการเรียกใช้ตัวอย่างก่อนหน้านี้:
ผลการวิเคราะห์: เซสชันจริง ๆ แล้วการดำเนินการสองครั้งเมื่อส่งการทำธุรกรรม เมื่อรวมกับกระบวนการอัปเดตในรหัสประการแรกจะมีการเพิ่มวัตถุผู้ใช้ใหม่แล้วดำเนินการการบันทึกการดำเนินการ มันจะเรียกคำสั่งแทรกจากนั้นการดำเนินการ setName จะทำในรหัสและชื่อจะปรับเปลี่ยนใหม่ อย่างไรก็ตามมันยังไม่ได้ซิงโครไนซ์กับฐานข้อมูลในเวลานี้ แต่อยู่ในหน่วยความจำ ในเวลานี้จะมีสองรัฐ เราบอกว่าบิตข้อมูลในเวลานี้เป็นข้อมูลที่สกปรกและในที่สุดก็อัปเดตไปยังฐานข้อมูลเมื่อส่งธุรกรรม