(update() อัพเดต หากไม่มีคีย์หลัก จะมีการรายงานข้อผิดพลาด
saveOrUpdate() บันทึกหรืออัพเดต ทำการแทรกโดยไม่มีคีย์หลัก
อัปเดต: เป็นการดำเนินการอัปเดตสำหรับวัตถุชั่วคราว (ชั่วคราว) หรือเพิ่งแยกออก (แยกออก) การดำเนินการอัปเดตสำหรับวัตถุชั่วคราวมักจะไม่มีผลกระทบ สำหรับวัตถุที่แยกออกมา การดำเนินการซิงโครไนซ์จะดำเนินการ กล่าวคือ ข้อมูลของฐานข้อมูลจะเปลี่ยนแปลง และสถานะของวัตถุก็กลายเป็นวัตถุที่ได้รับการจัดการด้วย
SaveOrUpdate: นอกจากนี้ยังดำเนินการชั่วคราวหรือแยกออกอีกด้วย ส่วนว่าจะแทรกหรืออัปเดตนั้นจะต้องวิเคราะห์ตามเงื่อนไขเฉพาะบางประการที่ระบุในรหัส อย่างไรก็ตาม โดยส่วนตัวผมคิดว่าเมื่อชัดเจนว่าจะมีเฉพาะการดำเนินการแทรกเท่านั้น ควรหลีกเลี่ยงการใช้ saveOrUpdate และใช้เพียงแค่บันทึกโดยตรง)
เริ่มต้นด้วยแนวคิดบางประการ:
ใน Hibernate แนวคิดหลักคือการจัดการสถานะของ PO PO มีสามสถานะ:
1. VO ที่ไม่คงอยู่
ในขณะนี้ เป็นออบเจ็กต์หน่วยความจำ VO และวงจรชีวิตได้รับการจัดการโดย JVM
2. PO ยังคงอยู่ และข้อมูลฐานข้อมูลจะถูกแมปในเวลานี้ในระหว่างวงจรชีวิตเซสชัน และฐานข้อมูลจะจัดการวงจรชีวิต
3. ยังคงมีอยู่ แต่ตอนนี้ถูกแยกออกจากเซสชันแล้ว หากคุณเรียกใช้ PO นี้ซึ่งแยกออกจากเซสชันเป็น VO คุณสามารถเข้าสู่เซสชันอื่นและจัดการสถานะ PO ต่อไปได้ในขณะนี้ ก็จะกลายเป็นสถานะ PO PO ประเภทนี้ข้ามจริง
เซสชันดำเนินการบำรุงรักษาสถานะ
ใน JDO1.x แบบเดิม PO จะมีเพียงสองสถานะแรกเท่านั้น เมื่อ PO ถูกแยกออกจาก PM แล้ว PO จะสูญเสียสถานะและไม่เกี่ยวข้องกับข้อมูลฐานข้อมูลอีกต่อไป
แม้ว่าคุณจะเพิ่ม PM ใหม่ แต่สถานะก็ไม่สามารถกู้คืนได้
จุดแข็งของ Hibernate คือหลังจากที่ PO ออกจากเซสชันแล้ว ยังสามารถรักษาสถานะได้ หลังจากเข้าสู่เซสชันใหม่ ความสามารถในการจัดการสถานะก็กลับคืนมา แต่ในเวลานี้ การจัดการสถานะ
คุณต้องใช้ session.update หรือ session.saveOrUpdate ซึ่งเป็นสิ่งที่ Hibernate Reference กล่าวถึงใน "ต้องใช้การเขียนโปรแกรมที่แตกต่างกันเล็กน้อย
แบบอย่าง"
ตอนนี้เข้าสู่หัวข้อนี้อย่างเป็นทางการ:
พูดง่ายๆ ก็คือ อัปเดต และ saveOrUpdate เพื่อจัดการสถานะของ PO แบบข้ามเซสชัน
สมมติว่า PO ของคุณไม่จำเป็นต้องข้ามเซสชัน ก็ไม่จำเป็นต้องใช้ PO ตัวอย่างเช่น หากคุณเปิดเซสชัน ดำเนินการ PO แล้วปิด คุณจะไม่ใช้ PO นี้อีก
จากนั้นไม่จำเป็นต้องใช้การอัพเดต
ลองดูตัวอย่างข้างต้น:
รหัสจาวา
Foo foo=sess.load(Foo.class,id);;
foo.setXXX(xxx);;
sess.flush();;
sess.commit();;
Foo foo=sess.load(Foo.class,id);; foo.setXXX(xxx);; sess.flush();;
การดำเนินการของอ็อบเจ็กต์ PO foo ทั้งหมดจะเสร็จสิ้นภายในวงจรชีวิตของเซสชัน ดังนั้นจึงไม่จำเป็นต้องดำเนินการอย่างชัดเจน เช่น sess.update(foo) ไฮเบอร์เนตจะตรวจจับโดยอัตโนมัติว่าวัตถุ foo มี
ได้รับการแก้ไขแล้ว ดังนั้น update sql จึงถูกส่งไปยังฐานข้อมูล แน่นอนว่าไม่ใช่เรื่องผิดหากคุณยืนยันที่จะเพิ่ม sess.update(foo) แต่ก็ไม่จำเป็นต้องทำเช่นนั้น
เซสชันข้ามหมายความว่าหลังจากปิดเซสชันแล้ว คุณยังคงใช้ออบเจ็กต์ PO นี้เป็น VO ในภายหลัง คุณแก้ไขคุณสมบัติภายนอกเซสชัน จากนั้นคุณต้องการเปิดอีกครั้ง
เปิดเซสชันและบันทึกการแก้ไขคุณลักษณะ VO ลงในฐานข้อมูล จากนั้นคุณจะต้องใช้การอัปเดต
รหัสจาวา
// ในเซสชั่นแรก
Cat cat = (Cat); firstSession.load (Cat.class, catId);;
Cat PotentialMate = แมวใหม่ ();;
firstSession.save (ศักยภาพ Mate);;
// ในระดับที่สูงกว่าของแอปพลิเคชัน
cat.setMate(ศักยภาพMate);;
// ต่อมาในเซสชันใหม่
SecondSession.update(cat); // อัพเดต cat
SecondSession.update(เพื่อน); // อัปเดตเพื่อน
// ในเซสชั่นแรก Cat cat = (Cat); firstSession.load(Cat.class, catId);; Cat PotentialMate = new Cat();;
firstSession.save(potentialMate);; // ในระดับที่สูงกว่าของแอปพลิเคชัน cat.setMate (potentialMate);;
เซสชันใหม่ SecondSession.update (cat); // อัปเดต cat SecondSession.update (เพื่อน); // อัปเดตเพื่อน
ออบเจ็กต์ cat และ mate จะได้รับในเซสชั่นแรก หลังจากปิดเซสชั่นแรกแล้ว พวกมันจะกลายเป็นสถานะที่สามของ PO และ PO ที่เซสชั่นได้แยกออกในเวลานี้
ข้อมูลสถานะของพวกเขายังคงอยู่ เมื่อเข้าสู่เซสชั่นที่ 2 ก็สามารถอัพเดตสถานะได้ทันที แต่เนื่องจากการดำเนินการแก้ไขบน cat: cat.setMate
(potentialMate) ดำเนินการนอกเซสชัน ไฮเบอร์เนตไม่ทราบว่ามีการแก้ไขวัตถุ cat เซสชันที่สองไม่ทราบการแก้ไขนี้ ดังนั้นจึงต้องมีความชัดเจน
โทร SecondSession.update(cat) เพื่อแจ้ง Hibernate ว่าวัตถุ cat ได้รับการแก้ไข และคุณต้องส่ง update sql
นี่คือบทบาทของการอัปเดต มันจะถูกเขียนเมื่อวัตถุ PO ซิงโครไนซ์สถานะข้ามเซสชันเท่านั้น เมื่อไม่จำเป็นต้องประมวลผลออบเจ็กต์ PO ข้ามเซสชัน
เมื่อดำเนินการจัดการสถานะ ไม่จำเป็นต้องเขียนการอัปเดต
พูดคุยเกี่ยวกับการใช้ saveOrUpdate:
ความแตกต่างระหว่าง saveOrUpdate และการอัปเดตอยู่ที่กลยุทธ์ที่ Hibernate นำมาใช้สำหรับ PO ในการจัดการสถานะ PO แบบข้ามเซสชัน
ตัวอย่างเช่น เมื่อคุณเขียน DAOImpl ให้เพิ่มคู่เข้ากับวัตถุ cat ตามที่กำหนดไว้ด้านล่าง:
รหัสจาวา
addMate โมฆะสาธารณะ (แมวแมว เพื่อนเมท);
เซสชันเซสชั่น = ...;
ทรานแซคตัน tx = ...;
session.update(แมว);;
cat.addMate(เพื่อน);;
tx.commit();;
เซสชั่น.ปิด();;
-
addMate สาธารณะ (Cat cat, Mate mate); { เซสชั่นเซสชั่น = ...; Transacton tx = ...;
cat.addMate(เพื่อน); tx.commit();;
แน่นอนว่าคุณต้องสรุปการดำเนินการ Hibernate ใน DAO เพื่อให้โปรแกรมเมอร์ชั้นธุรกิจและโปรแกรมเมอร์ Web Layer ไม่จำเป็นต้องรู้จัก Hibernate และโทรหา DAO โดยตรง
ณ จุดนี้ปัญหาเกิดขึ้น: มีข้อกำหนดเบื้องต้นที่จำเป็นสำหรับโค้ดข้างต้นเพื่อให้ทำงานได้อย่างถูกต้องนั่นคือพารามิเตอร์การเรียกเมธอด cat object ต้องเป็น PO ที่ยังคงอยู่นั่นคือควร
ขั้นแรกให้สอบถามจากฐานข้อมูลแล้วใช้เช่นนี้ แต่เห็นได้ชัดว่าโปรแกรมเมอร์ในระดับธุรกิจไม่ทราบถึงความลึกลับภายในนี้
เพื่อนของมัน เขาจะเรียกมันแบบนี้อย่างชัดเจน มีวัตถุ cat ตัวใหม่ออกมา แล้ว addMate:
รหัสจาวา
แมว แมว = แมวใหม่();;
cat.setXXX();;
daoimpl.addMate(แมว,เพื่อน);;
แมว แมว = แมวใหม่();; cat.setXXX();; daoimpl.addMate(cat,mate);;
แต่โปรดทราบว่าวัตถุ cat นี้เป็นเพียง VO ยังไม่คงอยู่ ไม่ใช่ PO และไม่เข้าเกณฑ์ที่จะเรียกวิธี addMate ดังนั้นการเรียกวิธี addMate จะไม่ไปที่จริง
หากต้องการส่งการอัปเดต sql ในฐานข้อมูล วัตถุ cat จะต้องถูกบันทึกลงในฐานข้อมูลก่อน หลังจากที่กลายเป็น PO อย่างแท้จริงเท่านั้นจึงจะมีคุณสมบัติสำหรับ addMate
คุณต้องทำเช่นนี้:
รหัสจาวา
แมว แมว = แมวใหม่();;
cat.setXXX();;
daoimpl.addCat(แมว);;
daoimpl.addMate(แมว,เพื่อน);;
แมวแมว = แมวใหม่ ();; cat.setXXX ();; daoimpl.addCat (แมว);;
อยู่กับแมวก่อน จากนั้นจึงดำเนินการอื่นๆ กับแมว ดังนั้นโปรแกรมเมอร์ในชั้นธุรกิจจะต้องรู้ว่าวัตถุ cat อยู่ในสถานะใด ไม่ว่าจะเป็นอันแรกหรืออันที่สาม
ถ้าเป็นประเภทแรก คุณต้องบันทึกก่อน แล้วจึง addMate ถ้าเป็นประเภทที่สาม ให้ addMate โดยตรง
แต่สิ่งที่ร้ายแรงที่สุดคือหากซอฟต์แวร์ทั้งหมดมีหลายเลเยอร์ cat object ที่โปรแกรมเมอร์ชั้นธุรกิจได้รับอาจเป็น cat ที่ส่งผ่านจากเลเยอร์เว็บแอปพลิเคชันด้านบนและตัวเขาเองก็ไม่รู้เรื่องนี้
ไม่ว่า cat จะเป็น VO ไม่คงอยู่ หรือคงอยู่ เขาก็ไม่มีทางเขียนโปรแกรมได้เลย
ดังนั้น DAOImpl ดังกล่าวจึงเป็นปัญหาอย่างเห็นได้ชัด มันจะทำให้เกิดกับดักการเขียนโปรแกรมมากมายสำหรับโปรแกรมเมอร์ชั้นธุรกิจต้องมีความเข้าใจอย่างลึกซึ้งเกี่ยวกับคู่ PO ของ DAO แต่ละคู่ที่พวกเขาเรียก
การจัดการของรัฐแบบใดที่ดำเนินการคุณต้องมีความเข้าใจอย่างลึกซึ้งเกี่ยวกับสถานะที่แน่นอนของวัตถุ PO ของเขาตลอดเวลาเพื่อให้แน่ใจว่าการเขียนโปรแกรมถูกต้อง เห็นได้ชัดว่ามันเป็นไปไม่ได้ แต่ด้วย
saveOrUpdate ปัญหาเหล่านี้แก้ไขได้อย่างง่ายดาย
ตอนนี้คุณต้องแก้ไขวิธี addMate:
รหัสจาวา
addMate โมฆะสาธารณะ (แมวแมว เพื่อนเมท);
เซสชันเซสชั่น = ...;
ทรานแซคตัน tx = ...;
session.saveOrUpdate(แมว);;
cat.addMate(เพื่อน);;
tx.commit();;
เซสชั่น.ปิด();;
-
addMate สาธารณะ (Cat cat, Mate mate); { เซสชัน = ... ; Transacton tx = ... ;
(cat);; cat.addMate(เพื่อน);
ดังที่กล่าวข้างต้น หากโปรแกรมเมอร์ชั้นธุรกิจส่งผ่านออบเจ็กต์ PO ที่ถูกคงอยู่ จากนั้นไฮเบอร์เนตจะอัปเดตออบเจ็กต์ cat (สมมติว่าโปรแกรมเมอร์ชั้นธุรกิจได้แก้ไขมันนอกเซสชัน)
cat) หากสิ่งที่ถูกส่งเข้ามาเป็นออบเจ็กต์ใหม่ ให้บันทึกออบเจ็กต์ PO ลงในฐานข้อมูล
BTW: การที่ไฮเบอร์เนตจะอัพเดตออบเจ็กต์ cat หรือบันทึกออบเจ็กต์ cat ในเวลานี้จะขึ้นอยู่กับการตั้งค่าของค่าที่ไม่ได้บันทึก
ด้วยวิธีนี้ โปรแกรมเมอร์ในชั้นธุรกิจไม่จำเป็นต้องกังวลเกี่ยวกับสถานะของ PO อีกต่อไป สำหรับพวกเขา มันไม่สำคัญว่า cat จะเป็นวัตถุใหม่ แค่ VO หรือถูกสอบถามจากฐานข้อมูล
โดยไม่คำนึงถึงออบเจ็กต์ PO คุณสามารถเพิ่มทั้งหมดลงใน addMate ได้โดยตรง:
รหัสจาวา
daoimple.addMate(แมว เพื่อน);;
daoimple.addMate(แมว เพื่อน);;
นี่คือสิ่งที่ saveOrUpdate ทำ
บทความนี้มาจากบล็อก CSDN โปรดระบุแหล่งที่มาเมื่อพิมพ์ซ้ำ: http://blog.csdn.net/zhrl0000/archive/2009/12/17/5027965.aspx
-