มีสองปัญหาที่เหลืออยู่ในตะกร้าสินค้าคือการจัดเก็บข้อมูลการสั่งซื้อแบบเรียงซ้อนและแคชหน้า ข้อมูลที่นี่หมายถึงตะกร้าสินค้าและรายการช้อปปิ้ง นั่นคือเมื่อเราเก็บข้อมูลของตะกร้าสินค้าลงในฐานข้อมูลเรายังเก็บข้อมูลของสินค้าช้อปปิ้งแต่ละรายการและคีย์ต่างประเทศเกี่ยวข้องซึ่งเกี่ยวข้องกับปัญหาการจัดเก็บแบบเรียงซ้อนในไฮเบอร์เนต ปัญหาแคชหน้าหมายถึงเวลาที่ผู้ใช้ยืนยันคำสั่งซื้อหากเขาคลิกกลับเขาจะกลับไปที่หน้าการยืนยันคำสั่งซื้อ หน้าการยืนยันคำสั่งซื้อตอนนี้ออกมาอีกครั้งและเซสชันยังคงอยู่ที่นั่นและข้อมูลยังคงเป็นข้อมูลในขณะนี้ เห็นได้ชัดว่านี่ไม่ใช่ผลลัพธ์ที่เราต้องการและเราจะวิเคราะห์ทีละคนในภายหลัง ส่วนนี้ส่วนใหญ่จะกล่าวถึงสินค้าคงคลังของข้อมูลการสั่งซื้อและการแคชของหน้า
1. การจัดเก็บข้อมูลการสั่งซื้อแบบเรียงซ้อนกัน
การจัดเก็บแบบเรียงซ้อนของสองตารางที่เกี่ยวข้องในไฮเบอร์เนตจำเป็นต้องได้รับการกำหนดค่า ที่นี่เราแนะนำวิธีการกำหนดค่าของคำอธิบายประกอบเป็นหลัก pojo ของคำสั่งคือ forder, pojo ของรายการช้อปปิ้งคือ sorder และ forder และ sorder เป็นความสัมพันธ์แบบหนึ่งต่อหลายคน ก่อนอื่นให้ตั้งค่าการกำหนดค่าคำอธิบายประกอบดังต่อไปนี้:
@ENTITY คลาสสาธารณะ FORDER ใช้ java.io.Serializable {// ละเว้นรหัสที่ไม่เกี่ยวข้อง ... รายการส่วนตัว <Sorder> soorders = new ArrayList <Sorder> (); @onetomany (cascade = cascadetype.all, fetch = fetchtype.lazy, mappedby = "forder") รายการสาธารณะ <order> getSorders () {return this.sorders; } โมฆะสาธารณะ setSorders (รายการ <Sorder> soorders) {this.sorders = soorders; }} @Entity Public Class Sorder ใช้ java.io.serializable {// ละเว้นรหัสที่ไม่เกี่ยวข้อง ... Forder Private Forder; @ManytoOne (fetch = fetchType.lazy) @Joincolumn (name = "fid") public forder getForder () {return this.forder; } โมฆะสาธารณะ SetForder (Forder Forder) {this.forder = forder; - หลังจากการกำหนดค่านี้เมื่อเราบันทึกรายการโฆษณาเราจะบันทึกรายการช้อปปิ้งและเชื่อมโยงคีย์ต่างประเทศโดยอัตโนมัติ แต่หลักฐานคือเราจำเป็นต้องตั้งค่าความสัมพันธ์ระหว่างพวกเขานั่นคือ setSorders () ใน forder, setForder () ใน soorder และคุณสมบัติในเอนทิตีที่สอดคล้องกับคีย์ต่างประเทศที่เกี่ยวข้องอื่น ๆ
ก่อนหน้านี้เมื่อเราเพิ่มรายการช้อปปิ้งลงในตะกร้าสินค้า Forder.setsorder (Sorder) ถูกดำเนินการ ตอนนี้เราจำเป็นต้องเพิ่ม forder ลงใน soorder ดังนั้นเราจึงเพิ่มลงในรหัสต้นฉบับดังต่อไปนี้:
// นี่คือรหัสในส่วนที่ 17 เราแทรกประโยคในช่วงกลาง @Service ("SorderService") ชั้นเรียนสาธารณะ SorderServiceImpl ขยาย BaseserviceImpl <order> ใช้ Sorderservice {@Override Public Forder Addsorder // ใช้เพื่อทำเครื่องหมายว่ามีรายการช้อปปิ้งที่ซ้ำกัน // รับเครื่องตรวจสอบรายการช้อปปิ้งปัจจุบัน soorder = productTosorder (ผลิตภัณฑ์); // ตัดสินว่ารายการช้อปปิ้งปัจจุบันซ้ำกันหรือไม่ หากมีการทำซ้ำให้เพิ่มปริมาณสำหรับ (Sorder Old: forder.getSorders ()) {ถ้า (old.getProduct (). getId (). เท่ากับ (sorder.getProduct (). getId ()) {// มีการทำซ้ำ ishave = true; หยุดพัก; }} // รายการช้อปปิ้งปัจจุบันไม่มีอยู่ในตะกร้าสินค้าถ้า (! ishave) {// เราแทรกประโยคที่นี่: // ก่อนที่จะเพิ่มรายการช้อปปิ้งลงในรายการช้อปปิ้งก่อนที่จะสร้างความสัมพันธ์ระหว่างรายการช้อปปิ้งและตะกร้าสินค้า แต่ในเวลานี้ ในเวลานั้นมีคีย์หลัก SOORDER.SETFORDER (FORDER); forder.getSorders (). เพิ่ม (sorder); } return forder; } @Override Public Sorder ProductTosorder (ผลิตภัณฑ์ผลิตภัณฑ์) {Sorder SoOrder = New Sorder (); soorder.setName (product.getName ()); soorder.setNumber (1); SOORDER.SETPRICE (product.getPrice ()); soorder.setProduct (ผลิตภัณฑ์); คืน Sorder; -ตกลงมาดูกันว่าการกระทำใดที่จะข้ามไปเมื่อคำสั่งยืนยัน:
ดังนั้นเราจึงไปที่ตรรกะในการ forderaction:
@Controller ("forderaction") @scope ("prototype") คลาสสาธารณะ Forteraction ขยาย baseaction <fortder> {@Override public forder forder getModel () {model = (forder) session.get ("forder"); โมเดลกลับ; } // ใช้ฟังก์ชั่นการจัดเก็บ cascaded ของตะกร้าสินค้า (คำสั่งซื้อ) และรายการช้อปปิ้ง (รายการโฆษณา) สตริงสาธารณะบันทึก () {// // ส่งรายการช้อปปิ้งในเซสชันไปยังวัตถุโมเดลปัจจุบัน // forder forder = (forder) เซสชัน ("forder"); // //model.setsorders (forder.getSorders ()); //forder.setAddress (model.getAddress ()); //forder.setName (model.getName ()); //forder.setphone (model.getphone ()); //forder.setRemark (model.getRemark ()); //forder.setUser(( user) session.get("user ")); //forder.setstatus สถานะใหม่ (1)); //forder.setPost (model.getPost ()); //forder.setPost (model.getPost ()); //forder.setUser(( user) session.get("user ")); //forder.setstatus สถานะใหม่ (1)); //forder.setPost (model.getPost ()); // // Cascaded Library (จำเป็นต้องกำหนดค่าในคำอธิบายประกอบของ XML หรือ POJO) ดังนั้นจึงจำเป็นต้องมีการเชื่อมโยง SOORDER FORDER // // เพิ่มลงใน SORDERSERVICICEIMPL class.SetForder (FORDER); //forderservice.save(Forder); model.setUser ((user) session.get ("ผู้ใช้")); model.setstatus (สถานะใหม่ (1)); ForderService.save (รุ่น); คืน "ธนาคาร"; - ดังที่เห็นได้จากรหัสด้านบนมีสองวิธี: วิธีแรกไม่ได้เอาชนะวิธี getModel (ส่วนที่ฉันแสดงความคิดเห็น) วิธีนี้ค่อนข้างโง่ เนื่องจาก forderaction สืบทอด baseaction และ baseaction ใช้อินเตอร์เฟส modeldriven ข้อมูลที่ส่งผ่านจะถูกห่อหุ้มลงในโมเดล โมเดลเป็นคุณสมบัติใน baseaction จากนั้นเราจำเป็นต้องส่งข้อมูลทั้งหมดในโมเดลไปยัง Forder ในเซสชันและจากนั้นข้อมูลใน Forder สามารถเรียงซ้อนกับ Sorder เพื่อเข้าสู่ห้องสมุด อย่างไรก็ตามวิธีนี้ค่อนข้างโง่ ... ดังนั้นเราจึงใช้วิธีที่สองเขียนวิธี getModel ใหม่และกำหนด Forder ให้กับโมเดลโดยตรงจากนั้นเราเพียงแค่ต้องเพิ่มรายการ cascading ในโมเดลนั่นคือรหัสที่ไม่ใช่คำอธิบายข้างต้น ด้วยวิธีนี้หลังจากผู้ใช้คลิกเพื่อยืนยันคำสั่งซื้อข้อมูลจะถูกป้อนลงในฐานข้อมูลและข้ามไปที่หน้าการชำระเงิน (ต้องทำหน้าชำระเงินต่อไปดังนั้นคุณสามารถข้ามไปยัง JSP ก่อนได้)
2. ปัญหาการแคชหน้า
ตอนนี้รายการการเรียงลำดับของข้อมูลการสั่งซื้อได้รับการแก้ไขแล้ว แต่หากผู้ใช้คลิกเพื่อยืนยันคำสั่งซื้อและกลับมาเราพบว่ามันยังคงเป็นหน้ายืนยันคำสั่งซื้อเดิมและข้อมูลยังคงเป็นข้อมูลในตอนนี้และเซสชันไม่ได้ปิดซึ่งหมายความว่าฉันต้องยืนยันข้อมูลการสั่งซื้ออีกครั้งซึ่งไม่เหมาะสม กล่าวอีกนัยหนึ่งเมื่อผู้ใช้คลิกเพื่อยืนยันคำสั่งซื้อเราไม่สามารถปล่อยให้แคชหน้าได้ ด้วยวิธีนี้เมื่อผู้ใช้คลิกกลับมันจะแสดงให้เห็นว่าหน้าหมดอายุแล้วและเราก็ปล่อยให้มันข้ามไปที่หน้าแรก
เรารู้ว่าสามารถตั้งค่าหน้า JSP front-end เพื่อให้เบราว์เซอร์ไม่แคชข้อมูลดังนั้นเราจึงสามารถตั้งค่าได้ดังต่อไปนี้ในหน้ายืนยันส่วนหน้า JSP:
แต่ปัญหาไม่ง่ายอย่างนั้น เพียงแค่ทำสิ่งนี้เป็นไปไม่ได้ หากคุณทำเช่นนี้ผู้ใช้จะคลิกกลับและจะแจ้งให้ทราบว่าหน้านั้นหมดอายุแล้ว อย่างไรก็ตามเมื่อผู้ใช้รีเฟรชและเป็นไปไม่ได้แคชจะถูกโหลดด้วยข้อมูลต้นฉบับ ดังนั้นเราจึงเข้าใจสิ่งหนึ่ง เนื่องจากเซสชั่นยังไม่ได้ปิดจึงมีข้อมูลการสั่งซื้อสำหรับ Forder ในเซสชัน ผู้ใช้จะยังคงได้รับ Forder นี้ต่อไปหลังจากรีเฟรชและข้อมูลการสั่งซื้อดั้งเดิมจะปรากฏขึ้น ดังนั้นการตั้งค่าสิ่งนี้ในแผนกต้อนรับไม่สามารถแก้ปัญหาได้เลย นอกจากนี้เรายังต้องทำการประมวลผลที่เกี่ยวข้องในพื้นหลัง
เนื่องจากเรารู้ปัญหาเราสามารถทำได้: เนื่องจากเมื่อผู้ใช้คลิกเพื่อยืนยันคำสั่งซื้อมันจะส่งมอบให้กับ forderaction และหลังจากการดำเนินการ fortderaction จะถูกประมวลผลมันจะข้ามไปยังหน้าการชำระเงิน เราสามารถทำเคล็ดลับบางอย่างใน Forderaction: เราล้าง Forder ดั้งเดิมในเซสชั่นใช่ไหม? สิ่งนี้เป็นไปได้ แต่เมื่อพิจารณาว่าคำสั่งซื้อยังคงเกี่ยวข้องกับคำสั่งซื้อเมื่อทำการชำระเงินในภายหลังเราสามารถบันทึก Forder ดั้งเดิมในเซสชั่นไปยังสถานที่อื่นและล้าง Forder ดั้งเดิม ดังนั้นเราจึงเพิ่มรหัสสองบรรทัดลงใน Forderaction ด้านบนดังนี้:
@Controller ("forderaction") @scope ("prototype") คลาสสาธารณะ Forteraction ขยาย baseaction <fortder> {@Override public forder forder getModel () {model = (forder) session.get ("forder"); โมเดลกลับ; } // ใช้ฟังก์ชั่นการจัดเก็บ cascaded ของตะกร้าสินค้า (คำสั่งซื้อ) และรายการช้อปปิ้ง (รายการโฆษณา) สตริงสาธารณะบันทึก () {// // ส่งรายการช้อปปิ้งในเซสชันไปยังวัตถุโมเดลปัจจุบัน // forder forder = (forder) เซสชัน ("forder"); // //model.setsorders (forder.getSorders ()); //forder.setAddress (model.getAddress ()); //forder.setName (model.getName ()); //forder.setphone (model.getphone ()); //forder.setRemark (model.getRemark ()); //forder.setUser(( user) session.get("user ")); //forder.setstatus สถานะใหม่ (1)); //forder.setPost (model.getPost ()); //forder.setPost (model.getPost ()); //forder.setUser(( user) session.get("user ")); //forder.setstatus สถานะใหม่ (1)); //forder.setPost (model.getPost ()); // // ที่เก็บของ cascaded (จำเป็นต้องกำหนดค่าในคำอธิบายประกอบของ XML หรือ POJO) ดังนั้น soorder จึงเชื่อมโยงกับ forder // // เพิ่มลงใน sorderserviceimpl class.save (forder); //forderservice.save(Forder); model.setUser ((user) session.get ("ผู้ใช้")); model.setstatus (สถานะใหม่ (1)); ForderService.save (รุ่น); // ตะกร้าสินค้าถูกเก็บไว้ในที่เก็บดังนั้นตะกร้าสินค้าในเซสชั่นดั้งเดิมควรถูกล้างเซสชัน ("OldForder", session.get ("FORDER")); // บันทึกข้อมูลรถเข็นช็อปปิ้งดั้งเดิมก่อนเพราะข้อมูลที่เกี่ยวข้องจะต้องชำระเงินในภายหลัง -จากนั้นเราต้องเพิ่มรหัสต่อไปนี้ในหน้ายืนยันแผนกต้อนรับ:
ตรรกะตอนนี้ชัดเจน ก่อนอื่นเมื่อหน้าการยืนยันคำสั่งซื้อ Forder มีข้อมูลดังนั้นจึงไม่ว่างเปล่า การตัดสินนี้ไม่ถูกต้อง เมื่อผู้ใช้คลิกเพื่อยืนยันคำสั่งซื้อใน Forderaction เราจะแทนที่ Forder ด้วยวัตถุ Forder ที่ว่างเปล่าซึ่งหมายความว่าข้อมูลต้นฉบับจะหายไป (เราบันทึกไว้ในคู่คีย์-ค่าอื่นในเซสชันสำหรับการชำระเงินในภายหลัง) ด้วยวิธีนี้เมื่อผู้ใช้คลิกกลับและกลับไปที่หน้าการยืนยันการสั่งซื้อตอนนี้การตัดสินจะมีผลและจะข้ามไปที่หน้าแรก ณ จุดนี้ตรรกะทั้งหมดเสร็จสมบูรณ์และปัญหาแคชหน้าได้รับการแก้ไข
ที่อยู่ดั้งเดิม: http://blog.csdn.net/eson_15/article/details/51433247
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น