รายชื่อรัฐ

และตอนนี้ความสนุกก็เริ่มขึ้น เราจะศึกษาสถานะของวัตถุเอนทิตี คุณต้องจ่ายทุกอย่างและสำหรับการใช้ไฮเบอร์เนตด้วย คุณไม่คิดว่าการเรียนรู้ 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