รายชื่อรัฐ
และตอนนี้ความสนุกก็เริ่มขึ้น เราจะศึกษาสถานะของวัตถุเอนทิตี คุณต้องจ่ายทุกอย่างและสำหรับการใช้ไฮเบอร์เนตด้วย คุณไม่คิดว่าการเรียนรู้ HQL มีราคาขนาดนั้นหรือ? ไม่ ชีวิตซับซ้อนขึ้นเล็กน้อย
หากคุณมีวัตถุเอนทิตีบางประเภทที่คุณสามารถบันทึกลงในฐานข้อมูลโดยใช้ Hibernate จากมุมมองของ Hibernate วัตถุนี้สามารถมีสี่สถานะ:
- ชั่วคราว
- ถาวร (หรือจัดการ)
- เดี่ยว
- ลบออก
และเพื่อให้คุณสนใจ ฉันจะเพิ่มรูปภาพนี้ในการบรรยายนี้:

ชั่วคราว
ในความเป็นจริงทุกอย่างง่ายกว่าที่คิดแม้ว่าจะไม่มีความแตกต่างก็ตาม ตัวอย่างเช่น ทุกอ็อบเจกต์เอนทิตีที่คุณสร้างขึ้นอย่างชัดเจนโดยใช้โค้ด Java และไม่ได้โหลดจากฐานข้อมูลโดยใช้ Hibernate จะมีสถานะชั่วคราว (โปร่งใส)
EmployeeEntity employee = new EmployeeEntity();
สถานะชั่วคราวหมายความว่า Hibernate ไม่มีความคิดเกี่ยวกับวัตถุนี้ และไม่มีการดำเนินการใดๆ กับวัตถุที่ส่งผลต่อ Hibernate และการทำงานของ Hibernate บนวัตถุนี้ก็ไม่มีผลเช่นกัน
อ็อบเจกต์ดังกล่าวเรียกอีกอย่างว่าPOJO - Plain Old Java Object คำนี้มักใช้ตรงข้ามกับวัตถุต่าง ๆ ที่มีพฤติกรรมยุ่งยาก จำวัตถุ Moc ที่ Mockito สร้างขึ้นได้ไหม นี่ไม่ใช่ POJO
หากรหัสไคลเอนต์บางตัวทำงานกับวัตถุที่มีสถานะชั่วคราว การโต้ตอบสามารถอธิบายได้ด้วยโครงร่างที่ง่ายมาก:

ถาวรหรือจัดการ
กรณีที่พบบ่อยที่สุดคือวัตถุที่เกี่ยวข้องกับเครื่องยนต์ไฮเบอร์เนต สถานะของพวกเขาเรียกว่าถาวร (หรือจัดการ) มีสองวิธีในการรับวัตถุที่มีสถานะนี้:
- โหลดวัตถุจากไฮเบอร์เนต
- บันทึกวัตถุในไฮเบอร์เนต
ตัวอย่าง:
Employee employee = session.load(Employee.class, 1);
Employee employee = new Employee ();
session.save(employee);
วัตถุดังกล่าวมักจะสอดคล้องกับบันทึกบางประเภทในฐานข้อมูล มี ID และอื่น ๆ ออบเจ็กต์นี้แนบมากับเซสชันไฮเบอร์เนต และโดยทั่วไปไม่สามารถแสดงโดยอ็อบเจ็กต์จริง แต่ใช้พร็อกซีบางประเภท
ค่อนข้างเป็นไปได้ว่าหลังจากเรียกใช้ เมธอด session.load()คุณจะได้รับวัตถุต้นขั้ว (พร็อกซี) กลับมา และการเรียกทั้งหมดไปยังฐานข้อมูลจะดำเนินการหลังจากเรียกใช้เมธอดของวัตถุนี้เท่านั้น แต่เราจะพูดถึงรายละเอียดดังกล่าวในภายหลัง
และการทำงานร่วมกันของรหัสไคลเอ็นต์และวัตถุในสถานะ Managed สามารถอธิบายได้ด้วยรูปภาพต่อไปนี้:

เดี่ยว
สถานะต่อไปคือเมื่อวัตถุถูกแยกออกจากเซสชัน นั่นคือ เมื่อแนบอ็อบเจ็กต์กับเซสชัน Hibernate แล้ว แต่เซสชันถูกปิดหรือการทำธุรกรรมสิ้นสุดลง และ Hibernate จะไม่ตรวจสอบอ็อบเจ็กต์นี้อีกต่อไป
ตัวอย่าง:
session.close();
session.evict(entity);
ในตัวอย่างแรก เซสชันถูกปิด ในกรณีที่สอง เราได้ระบุอย่าง ชัดเจนว่าเราต้องการแยกวัตถุออกจากเซสชันโดยใช้ เมธอด evict()
โครงร่างการโต้ตอบของโค้ดและวัตถุใหม่จะมีลักษณะดังนี้:

และนี่คือจุดที่น่าสนใจ หากได้รับวัตถุของคุณจาก Hibernate เป็นไปได้ว่าคุณได้รับพร็อกซีแทนที่จะเป็นวัตถุจริง และวัตถุพร็อกซีนี้ หลังจากตัดการเชื่อมต่อจากเซสชัน จะส่งข้อยกเว้นเมื่อมีการเรียกใช้เมธอด
นี่เป็นปัญหาที่พบบ่อยที่สุดสำหรับผู้เริ่มต้นเมื่อทำงานกับไฮเบอร์เนต คุณจำเป็นต้องรู้คำตอบสำหรับคำถามเช่นนี้ในเวลาใดก็ตามเมื่อคุณทำงานกับวัตถุเอนทิตี :
- คุณมีวัตถุจริงหรือเพียงแค่พร็อกซีจากวัตถุจริงหรือไม่?
- คุณกำลังทำธุรกรรมอยู่หรือไม่?
- เป็นธุรกรรมแบบอ่านเขียนหรือธุรกรรมแบบอ่านอย่างเดียว
- วัตถุถูกจัดการโดยกลไก LazyLoading หรือไม่
- ส่วนใดของวัตถุที่โหลดไว้ในหน่วยความจำแล้ว และส่วนใดที่จะถูกโหลดเมื่อเข้าถึง
- วัตถุของคุณเชื่อมต่อกับวัตถุที่อ้างอิงอย่างไร
ข่าวดีก็คือส่วนใหญ่มักจะเห็นได้ชัด แต่คุณยังต้องเข้าใจว่ามันทำงานอย่างไรภายใต้ประทุน การเขียนโปรแกรมเชิงประกาศคือสิ่งที่เป็น - คุณสามารถเขียนโค้ดได้ภายใน 10 นาที เข้าใจว่าทำไมมันถึงไม่ทำงานอย่างที่ควรจะเป็น - ใน 10 ชั่วโมง :)
ลบออก
และสถานะสุดท้ายที่วัตถุเอนทิตีของคุณสามารถมีได้จะถูกลบออก อย่างที่คุณอาจเดาได้จากชื่อของมัน นี่คือสถานะของวัตถุระยะไกล
สถานะนี้ปรากฏขึ้นเนื่องจากข้อเท็จจริงที่ว่าหากคุณลบวัตถุบางอย่างออกจากฐานข้อมูล วัตถุ Java จะไม่หายไปทุกที่ในทันที
Employee employee = session.load(Employee.class, 1);
//after loading the object's state is Persisted
session.remove(employee);
//after deletion, the state of the object is Removed
session.save(employee);
//and now Persisted again
session.close();
//and now the Detached state
GO TO FULL VERSION