เมื่อเร็ว ๆ นี้เนื่องจากความต้องการทางธุรกิจในระบบอีคอมเมิร์ซฉันต้องกลับไปที่รหัสผลิตภัณฑ์หลังจากแทรกข้อมูลผลิตภัณฑ์ ในตอนแรกฉันพบข้อผิดพลาดบางอย่างดังนั้นฉันจึงจดบันทึกที่นี่เพื่อป้องกันไม่ให้ถูกลืมในอนาคต
รับคีย์หลักที่แทรกเช่นรหัสต่อไปนี้
ผู้ใช้ผู้ใช้ = ผู้ใช้ใหม่ (); user.setUserName ("Chenzhou"); user.setPassword ("xxxx"); user.setComment ("ทดสอบฟังก์ชั่นของการแทรกข้อมูลเพื่อส่งคืนคีย์หลัก"); System.out.println ("คีย์หลักก่อนการแทรกคือ:"+user.getUserId ()); userdao.insertandgetId (ผู้ใช้); // แทรกการทำงาน System.out.println ("คีย์หลักหลังจากการแทรกคือ:"+user.getUserId ());หลังจากสอบถามข้อมูลออนไลน์ฉันพบว่ามีประมาณสองวิธี
วิธีที่ 1:
ในไฟล์การแม็พของคลาสเอนทิตี "*mapper.xml" ถูกเขียนขึ้นเช่นนี้:
<insert id = "insertandgetId" useGeneratedKeys = "true" keyProperty = "userId" parameterType = "com.chenzhou.mybatis.user"> แทรกลงในผู้ใช้ (ชื่อผู้ใช้รหัสผ่านความคิดเห็น) ค่า (#{username},#},#},#เคล็ดลับ:
useGeneratedKeys = "true" หมายถึงการตั้งค่าการเติบโตของตนเองสำหรับคีย์หลัก
keyProperty = "userId" หมายถึงการกำหนด ID ที่เพิ่มขึ้นให้กับฟิลด์ UserID ในคลาสเอนทิตี
parameterType = "com.chenzhou.mybatis.user" คุณสมบัตินี้ชี้ไปที่คลาสพารามิเตอร์พารามิเตอร์ที่ผ่าน
นี่คือการเตือนว่าไม่มีแอตทริบิวต์ผลลัพธ์ใน <แทรก> </insert> ดังนั้นอย่าเพิ่มแบบสุ่ม
uerid ในคลาสเอนทิตีจะต้องมี getter () และ setter (); วิธี
เนื่องจากฉันได้ตั้งค่าการเติบโตของตัวเองในฟิลด์แล้วเมื่อสร้างตารางในฐานข้อมูล MySQL ในที่สุดฉันก็เลือกวิธีที่สอง
วิธีที่สอง:
นอกจากนี้ในไฟล์การแมป "*mapper.xml" ของคลาสเอนทิตี แต่ควรเขียนเช่นนี้:
<!-แทรกผลิตภัณฑ์-> <insert id = "insertProduct" parameterType = "domain.model.productBean"> <selectKey resultSpe = "java.lang.long" order = "หลังจาก" keyProperty = "productId"> เลือก last_insert_id () t_product (ProductName, ProductDesrcible, PerchantId) ค่า (#{productName},#{productDesrcible},#{merchantId}); </แทรก>เคล็ดลับ:
ไม่มีแอตทริบิวต์ผลลัพธ์ใน <แทรก> </insert> แต่มีแท็ก <SelectKey> </electKey>
order = "หลังจาก" หมายความว่าคำสั่งแทรกจะถูกดำเนินการก่อนจากนั้นคำสั่งการสืบค้นจะถูกดำเนินการ
สามารถตั้งค่าเป็นก่อนหรือหลัง
หากตั้งค่าไว้ก่อนหน้านี้จะเลือกคีย์หลักก่อนตั้งค่า keyProperty จากนั้นเรียกใช้คำสั่งแทรก
หากตั้งค่าเป็นหลังจากนั้นเรียกใช้คำสั่งแทรกก่อนจากนั้นองค์ประกอบ SelectKey - คล้ายกับฐานข้อมูล Oracle คุณสามารถฝังการเรียกลำดับในคำสั่งแทรกเช่นในฐานข้อมูล Oracle
keyProperty = "userId" หมายถึงการกำหนด ID ที่เพิ่มขึ้นให้กับฟิลด์ UserID ในคลาสเอนทิตี
เลือก last_insert_id () หมายความว่า ID การเติบโตของตัวเองของบันทึกที่เพิ่งแทรกถูกสอบถามในไวยากรณ์ MySQL
uerid ในคลาสเอนทิตีจะต้องมี getter () และ setter (); วิธี
เพื่อให้บรรลุความต้องการข้างต้นก็เพียงพอแล้ว
หากคุณสนใจที่นี่โปรดฟังฉันเกี่ยวกับความผิดพลาดที่อาจเกิดขึ้นใน mybatis ต่อไป
เหตุใดการปรับเปลี่ยนวิธีการเพิ่มใน mybatis เพื่อให้มีค่าส่งคืนแม้ว่ามันจะแจ้งให้ทราบว่าฐานข้อมูลการแทรกสำเร็จและข้อมูลที่แทรกสามารถอ่านได้ แต่เมื่อคุณเปิดฐานข้อมูลคุณจะไม่เห็นข้อมูลที่แทรก?
หากคุณต้องการแทรกและส่งคืนคีย์หลักเมื่อใช้ข้อกำหนดข้างต้นอย่าลืมเขียนด้วยวิธีนี้
@Override Public Long InsertProduct (ProductBean ProductBean) {// วิธีการที่สร้างขึ้นอัตโนมัติ todo stub sqlsession เซสชัน = myBatisjdbcutil.currentsession (); productidao productidao = session.getMapper (productidao.class); // ที่นี่ *.class // จะต้องสอดคล้องกับเลเยอร์อินเตอร์เฟสของ DAO RETURN ProductIdao.InsertProduct (ProductBean); -ทำไม
เพราะถ้าคุณเขียนเหมือนด้านบนการส่งคืนรหัสคีย์หลักที่คุณต้องการหลังจากการดำเนินการไม่ใช่จำนวนแถวที่ได้รับผลกระทบหลังจากดำเนินการคำสั่งฐานข้อมูล
ยิ่งกว่านั้นหลังจากที่คุณดำเนินการคุณจะพบว่าพรอมต์นั้นประสบความสำเร็จในการแทรกและคุณยังสามารถอ่านข้อมูลที่แทรกด้วยรหัส แต่มีเพียงหนึ่งระเบียนเสมอ
ยิ่งกว่านั้นเมื่อคุณเปิดฐานข้อมูลคุณจะพบว่าไม่มีการแทรกข้อมูลในฐานข้อมูลได้สำเร็จ
ฉันรู้สึกหดหู่ที่นี่เป็นเวลานานและในที่สุดก็ค้นพบประเด็นสำคัญ
ความแตกต่างระหว่างการมีค่าส่งคืนและไม่มีค่าส่งคืนคือ:
ค่าที่ส่งคืนเป็นเพียงการเข้าถึงโหมดอ่านฐานข้อมูลเท่านั้นและจะไม่มีการปรับเปลี่ยนข้อมูลฐานข้อมูลเช่นวิธีการสอบถามต่างๆ
หากไม่มีค่าส่งคืนฐานข้อมูลจะถูกเข้าถึงในโหมดอ่านและเขียนและข้อมูลในฐานข้อมูลจะถูกแก้ไขเช่นการลบและการเพิ่ม
นอกจากนี้ตามความเข้าใจส่วนบุคคล MyBatis ควรแคชไว้ก่อนที่จะเป็นคอลเลกชันที่สร้างขึ้นมาเมื่อใช้งานคำสั่งแทรกแล้วเรียกไดรเวอร์พื้นฐานเพื่อใช้งานและแก้ไขฐานข้อมูล
session.commit (); mybatisjdbcutil.closesession ();
คำสั่งสองข้อความข้างต้นจะไม่ถูกส่งคืนซึ่งหมายความว่าหลังจากดำเนินการตามคำสั่งทั้งสองนี้แล้วพวกเขาจะถูกดำเนินการอย่างแท้จริงและแทรกลงในฐานข้อมูลและแก้ไขข้อมูลในฐานข้อมูล
ในทางตรงกันข้ามหากมีค่าส่งคืนข้อความทั้งสองนี้จะไม่ถูกดำเนินการดังนั้นคำสั่งเพิ่มเติมจะถูกดำเนินการเฉพาะในเซสชันที่สร้างขึ้นด้วยตัวเอง แต่มันไม่ได้ส่งไปยังฐานข้อมูลดังนั้นจึงไม่มีระเบียนในฐานข้อมูล
สิ่งนี้อธิบายได้ว่าทำไมหลังจากแก้ไขวิธีการเพิ่มใน mybatis เพื่อให้มีค่าส่งคืนแม้ว่ามันจะแจ้งให้ทราบว่าฐานข้อมูลนั้นถูกแทรกสำเร็จคุณไม่สามารถเห็นข้อมูลที่แทรกได้เมื่อคุณเปิดฐานข้อมูล
วิธีคำสั่งการแทรกใน mybatis ไม่ควรมีค่าคืนเนื่องจากการเขียนเช่นนี้ถูกต้อง
@Override โมฆะสาธารณะ InsertProduct (ProductBean ProductBean) {// วิธีการที่สร้างขึ้นอัตโนมัติ todo stub sqlsession เซสชัน = mybatisjdbcutil.currentsession (); productidao productidao = session.getMapper (productidao.class); // ที่นี่ *.class // มันจะต้องสอดคล้องกับเลเยอร์อินเตอร์เฟสของ DAO Productidao.insertProduct (ProductBean); session.commit (); mybatisjdbcutil.closesession (); -ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น