บางครั้งจำเป็นต้องมีการตัดสินความปลอดภัยบางอย่างในเงื่อนไขของคำสั่ง SQL ตัวอย่างเช่นหากพารามิเตอร์ที่ส่งผ่านว่างเปล่าเมื่อสอบถามตามเงื่อนไขที่แน่นอนผลลัพธ์การสืบค้นจะว่างเปล่าในเวลานี้ บางทีเมื่อเราต้องการให้พารามิเตอร์ว่างเปล่าเราจะพบข้อมูลทั้งหมด ใช้ฟังก์ชั่นลำดับของ Oracle และ MySQL เพื่อสร้าง ID ในเวลานี้เราสามารถใช้ SQL แบบไดนามิก ทั้งหมดต่อไปนี้คือไวยากรณ์และฟังก์ชั่น MySQL (เช่นฟังก์ชั่นเชื่อมโยงสตริง)
SelectKey Tag
ในคำสั่งแทรก Oracle มักใช้ลำดับและฟังก์ชั่นใน MySQL เพื่อสร้างคีย์หลักของตารางแทรกโดยอัตโนมัติและจำเป็นต้องใช้วิธีการเพื่อส่งคืนคีย์หลักที่สร้างขึ้นนี้ เอฟเฟกต์นี้สามารถทำได้โดยใช้แท็ก SelectKey ของ MyBatis ตัวอย่างต่อไปนี้คือการใช้ฟังก์ชั่นฐานข้อมูล MySQL Custom NextVal ('นักเรียน') เพื่อสร้างคีย์และตั้งค่าเป็นคุณสมบัติของ StudentId ในคลาสเอนทิตีที่ผ่าน ดังนั้นหลังจากดำเนินการวิธีนี้ขอบสามารถรับคีย์ที่สร้างขึ้นผ่านคลาสเอนทิตีนี้
<!-ใส่คีย์หลักของนักเรียนโดยอัตโนมัติ-> <insert id = "createstudentautokey" parameterType = "liming.student.manager.data.model.studententity" keyProperty = "studentId"> student_tbl (student_id, student_name, student_sex, student_birthday, student_photo, class_id, place_id) ค่า ( #{studentid}, #{studentname}, #{studentsex}, #{studentbirthday}, #{studentphoto, javatype = byte typeHandler = org.apache.ibatis.type.blobtypehandler}, #{classid}, #{placeid}) </insert>
วิธีการโทรแบบอินเทอร์เฟซและรับการสร้างคีย์อัตโนมัติ
Entity Studententity = New Studententity (); entity.setStudentName ("สวัสดีรุ่งอรุณ"); entity.setstudentsex (1); entity.setstudentbirthday (dateutil.parse ("1985-05-28")); Entity.setClassID ("20000001"); entity.setplaceid ("70000001"); this.dynamicsqlmapper.createstudentautokey (เอนทิตี); System.out.println ("รหัสนักเรียนใหม่:" + entity.getStudentId ());
SELECTKEY คำสั่งรายละเอียดการกำหนดค่าคุณสมบัติคุณสมบัติ:
| คุณสมบัติ | อธิบาย | รับค่า |
| คีย์ไพรซ์ | แอตทริบิวต์ที่ต้องตั้งค่าสำหรับผลลัพธ์ที่สร้างโดยคำสั่ง SelectKey | |
| ผลการแข่งขัน | สร้างประเภทผลลัพธ์ MyBatis อนุญาตให้ใช้ประเภทข้อมูลพื้นฐานรวมถึงประเภทสตริงและ int | |
| คำสั่ง | 1: ก่อนหน้านี้คีย์หลักจะถูกเลือกก่อนจากนั้นจะตั้งค่า keyProperty จากนั้นคำสั่งแทรกจะถูกดำเนินการ; 2: หลังจากนั้นให้เรียกใช้คำสั่งแทรกก่อนจากนั้นคำสั่ง SelectKey | ก่อน หลังจาก |
| คำแถลง attementtype | MyBatis สนับสนุนคำสั่งแบบฟอร์มคำสั่งที่เตรียมและเรียกได้ซึ่งสอดคล้องกับคำสั่งการตอบสนองที่เตรียมไว้และการตอบรับ callablestatement | คำแถลง เตรียมไว้ ซึ่งเรียกได้ |
ถ้าแท็ก
หากแท็กสามารถใช้ในคำสั่ง SQL หลายประเภทให้ลองใช้การสืบค้นเป็นตัวอย่าง ก่อนอื่นมาดูแบบสอบถามทั่วไป:
<!-รายการนักเรียนแบบสอบถามเช่นชื่อ-> <select id = "getStudentListlikename" parameterType = "studentEntity" resultmap = "StudentResultMap"> เลือก * จาก Student_tbl St St.Student_name เช่น concat (concat ('%' อย่างไรก็ตามหากนักศึกษาชื่อหรือ StudentSex เป็นโมฆะในเวลานี้คำสั่งนี้มีแนวโน้มที่จะรายงานข้อผิดพลาดหรือผลการสอบถามว่างเปล่า ในเวลานี้เราใช้คำสั่ง IF Dynamic SQL เพื่อตัดสินก่อน หากค่าเป็นโมฆะหรือเท่ากับสตริงที่ว่างเปล่าเราจะไม่ตัดสินเกี่ยวกับเงื่อนไขนี้และเพิ่มความยืดหยุ่น
พารามิเตอร์คือ Entity Class Studententity คุณลักษณะทั้งหมดในคลาสเอนทิตีจะถูกตัดสินและหากพวกเขาไม่ว่างเปล่าเงื่อนไขการตัดสินจะถูกดำเนินการ
<!-2 ถ้า (พารามิเตอร์การตัดสิน)-ใช้คุณสมบัติที่คลาสเอนทิตีไม่ว่างเปล่าตามเงื่อนไข-> <select id = "getStudentList_if" resultmap = "resultmap_studententity" parameterType = "liming.student.Manager.data.model.studentity St.Student_birthday, St.Student_photo, St.Class_id, St.Place_id จาก Student_tbl st โดยที่ <ถ้า test = "studentName! = null"> St.Student_name ชอบ concat (concat ('%', #{studentName, jdbctype = varchar}) "> และ St.Student_sex = #{StudentSex, jdBcType = จำนวนเต็ม} </ถ้า> <ถ้า test =" studentBirthday! = null "> และ St.Student_Birthday = #{studentBirthday, JdbcType = วันที่} #{classid, jdbcType = varchar} </if> <ถ้า test = "classEntity! = null และ classEntity.classId! = null และ classEntity.classId! = ''"> และ st.class_id = #{classEntity.classid, jdbctype = varchar St.Place_id = #{placeid, jdbcType = varchar} </ถ้า> <ถ้าทดสอบ = "placeentity! = null และ placeentity.placeid! = null และ placeentity.placeid! St.Student_id = #{studentId, jdbcType = varchar} </if> </select>เมื่อใช้งานหากคุณต้องการใช้คุณจะต้อง จำกัด เงื่อนไขสำหรับคลาสเอนทิตีใหม่ คุณจะต้องแนบค่าที่สอดคล้องกันกับที่เงื่อนไข ในทางตรงกันข้ามถ้าคุณไม่ได้กำหนดค่าคุณไม่สามารถตัดสินได้ว่าที่ไหน
โมฆะสาธารณะ select_test_2_1 () {entity entity studententity = new Studententity (); entity.setStudentName (""); entity.setstudentsex (1); entity.setstudentbirthday (dateutil.parse ("1985-05-28")); Entity.setClassID ("20000001"); //entity.setplaceid("70000001 "); รายการ <studentEntity> list = this.dynamicsqlmapper.getStudentList_if (เอนทิตี); สำหรับ (studententity e: list) {system.out.println (e.toString ()); -
ถ้า + โดยการตัดสินตามเงื่อนไข
ชุดค่าผสมดังกล่าวอาจทำให้เกิดข้อผิดพลาดเมื่อเงื่อนไขที่ใช้มากขึ้นหากแท็ก ลองใช้คำสั่ง Query ใน 3.1 เป็นตัวอย่างเมื่อรหัส Java ถูกเรียกดังนี้:
@Test โมฆะสาธารณะ select_test_2_1 () {entity studententity = new Studententity (); entity.setStudentName (NULL); entity.setstudentsex (1); รายการ <studentEntity> list = this.dynamicsqlmapper.getStudentList_if (เอนทิตี); สำหรับ (studententity e: list) {system.out.println (e.toString ()); - หากตัวอย่างข้างต้นเป็น NULL คอลัมน์ student_name จะไม่ถูกตัดสินและข้อผิดพลาดพิเศษ SQL สำหรับ "คำหลักที่และ" จะได้รับโดยตรง
ในเวลานี้เราสามารถใช้ที่คำสั่งแบบไดนามิกเพื่อแก้ปัญหา แท็ก "ที่ไหน" จะรู้ว่าถ้าแท็กมีค่าส่งคืนมันจะแทรก 'ที่ไหน' นอกจากนี้หากเนื้อหาที่ส่งคืนโดยแท็กเริ่มต้นด้วยและหรือหรือหรือจะถูกลบออก
ตัวอย่างข้างต้นได้รับการแก้ไขเป็น:
<!- 3 เลือก- โดยที่/ถ้า (พารามิเตอร์การตัดสิน)- ใช้คุณสมบัติที่คลาสเอนทิตีไม่ว่างเปล่าตามเงื่อนไขที่-> <select id = "getStudentList_whereif" resultmap = "resultmap_studententity" พารามิเตอร์ liming.student.student.student St.Student_Birthday, St.Student_photo, St.Class_id, St.Place_id จาก Student_tbl st <โดยที่> <ถ้า test = "studentName! = null"> St.Student_name ชอบ concat (concat ('%', #{studentName, jdbcType = varchar}) '' '> และ St.Student_sex = #{StudentSex, jdBcType = จำนวนเต็ม} </ถ้า> <ถ้า test = "StudentBirthday! = null"> และ St.Student_Birthday = #{studentBirthday #{classId, jdbcType = varchar} </if> <ถ้า test = "classEntity! = null และ classEntity.classId! = ''"> และ st.class_id = #{classEntity.classid, jdbctype = varchar} </ถ้า> jdbcType = varchar} </if> <ถ้า test = "placeentity! = null และ placeentity.placeid! = null และ placeentity.placeid! = ''"> และ stataple_id = #{placeEntity.placeid, jdbctype = varchar} </ถ้า> jdbcType = varchar} </if> </where> </select> อัปเดตคำสั่งสำหรับ if + set
เมื่อไม่ได้ใช้แท็ก IF ในคำสั่ง UPDATE หากมีพารามิเตอร์ NULL มันจะทำให้เกิดข้อผิดพลาด
เมื่อใช้ IF TAGS ในคำสั่ง UPDATE หากก่อนหน้านี้ไม่ได้ดำเนินการอาจส่งผลให้เกิดข้อผิดพลาดซ้ำซ้อนของเครื่องหมายจุลภาค ใช้แท็กชุดเพื่อกำหนดค่าคำหลักที่ตั้งค่าแบบไดนามิกและเพื่อลบเครื่องหมายจุลภาคที่ไม่เกี่ยวข้องใด ๆ ต่อผนวกเข้ากับจุดสิ้นสุดของเงื่อนไข
หลังจากแก้ไขด้วยแท็ก IF+SET หากรายการเป็นโมฆะมันจะไม่ได้รับการอัปเดต แต่ค่าฐานข้อมูลดั้งเดิมจะได้รับการบำรุงรักษา ตัวอย่างต่อไปนี้:
<!-4 if/set (พารามิเตอร์การตัดสิน)-อัปเดตแอตทริบิวต์ที่คลาสเอนทิตีไม่ว่างเปล่า-> <update id = "updatestudent_if_set" parameterType = "liming.student.manager.data.model.studententity" update_tbl <et> #{studentName}, </ถ้า> <ถ้า test = "studentsex! = null และ studentsex! = ''"> student_tbl.student_sex = #{studentsex}, </if> <ถ้า test = "studentbirthday! "> student_tbl.student_photo = #{studentphoto, javatype = byte [], jdbctype = blob, typehandler = org.apache.ibatis.type.blobtypehandler} ! = '' "> student_tbl.place_id = #{placeId} </if> </set> โดยที่ student_tbl.student_id = #{studentId}; </update> ถ้า + ตัดแต่งแทนที่จะเป็นแท็กที่ไหน/ตั้งค่า
TRIM เป็นสถานที่ที่ยืดหยุ่นมากขึ้นในการไปที่แท็กคำหลักซ้ำซ้อนซึ่งสามารถฝึกฝนผลกระทบของสถานที่และตั้งค่า
ตัดแต่งแทนที่จะอยู่ที่ไหน
<!-5.1 if/trim แทนที่โดยที่ (พารามิเตอร์การตัดสิน)-ใช้แอตทริบิวต์ที่คลาสเอนทิตีไม่ว่างเปล่าตามเงื่อนไข-> <select id = "getStudentList_if_trim" resultmap = "resultmap_studententity" St.Student_id, St.Student_name, St.Student_sex St.Place_id จาก Student_tbl st <trim prefix = "โดยที่" prefixoverrides = "และ | หรือ"> <ถ้า test = "studentName! = null"> St.Student_name ชอบ concat (concat ('%', #{studentName, jdbctype = varchar}) St.Student_sex = #{studentsex, jdbcType = จำนวนเต็ม} </ถ้า> <ถ้าทดสอบ = "studentbirthday! = null"> และ St.Student_birthday = #{studentbirthday, jdbcType = วันที่} </ถ้า> jdbcType = varchar} </if> <ถ้า test = "classEntity! = null และ classEntity.classId! = null และ classEntity.classId! = ''"> และ st.class_id = #{classEntity.classid, jdbctype = varchar} #{placeid, jdbcType = varchar} </ถ้า> <ถ้า test = "placeentity! = null และ placeentity.placeid! = null และ placeentity.placeid! = ''"> และ St.Place_id = #{place.place.place.dlessid, jdbctype = varchar} #{studentId, jdbcType = varchar} </if> </trim> </select>
ตัดแต่งแทนชุด
<!-5.2 if/trim แทนที่ชุด (พารามิเตอร์การตัดสิน)-อัปเดตแอตทริบิวต์ที่คลาสเอนทิตีไม่ว่างเปล่า-> <อัปเดต id = "updatestudent_if_trim" parameterType = "liming.student.manager.data.model.studentEntity"> update student_tbl studentName! = '' "> student_tbl.student_name = #{studentName}, </ถ้า> <ถ้า test =" studentsex! = null และ studentsex! = '' "> student_tbl.student_sex = #{studentsex}, </ถ้า> #{studentbirthday}, </if> <ถ้า test = "studentphoto! = null"> student_tbl.student_photo = #{studentphoto, javatype = byte [], jdbctype = blob, typeHandler = org.apache.ibatis.ype.by.bypehandler student_tbl.class_id = #{classid}, </if> <ถ้า test = "placeid! = ''"> student_tbl.place_id = #{placeid} </ถ้า> </trim> โดยที่ student_tbl.student_id = #{studentId} เลือก (เมื่อมิฉะนั้น)
บางครั้งเราไม่ต้องการใช้เงื่อนไขทั้งหมด แต่เพียงเลือกหนึ่งจากตัวเลือกหลายตัวเลือก เมื่อใช้แท็ก IF ตราบใดที่นิพจน์ในการทดสอบเป็นจริงเงื่อนไขในแท็ก IF จะถูกดำเนินการ MyBatis จัดเตรียมองค์ประกอบทางเลือก หากแท็กคือความสัมพันธ์กับ (และ) และเลือกคือความสัมพันธ์กับ (หรือ)
แท็กตัวเลือกคือการพิจารณาว่าเงื่อนไขการทดสอบในภายในเมื่อแท็กนั้นถูกต้องตามลำดับหรือไม่ หากมีความถูกต้องตัวเลือกจะสิ้นสุดลง เมื่อเงื่อนไขทั้งหมดในการเลือกไม่เป็นที่พอใจ SQL ในมิฉะนั้นจะถูกดำเนินการ คล้ายกับคำสั่งสวิตช์ของ Java เลือกสวิตช์เมื่อเคสและค่าเริ่มต้นเป็นอย่างอื่น
ตัวอย่างเช่นตัวอย่างต่อไปนี้ยังเขียนเงื่อนไขทั้งหมดที่สามารถ จำกัด และใช้งานได้ เลือกจะเลือกการดำเนินการ SQL ด้วยการทดสอบจริงจากบนลงล่างเมื่อแท็ก สำหรับการพิจารณาความปลอดภัยเราใช้สถานที่ที่จะสรุปทางเลือกและวางคำหลักมากกว่าข้อผิดพลาด
<!-6 เลือก (พารามิเตอร์การตัดสิน)-ใช้คุณสมบัติแรกของคลาสเอนทิตีที่ไม่ว่างเปล่าตามลำดับตามเงื่อนไข-> <select id = "getStudentList_Choose" resultmap = "resultmap_studentity" parametertype = "liming.student.student.student.student.student St.Student_sex, St.Student_Birthday, St.Student_photo, St.Class_id, St.Place_id จาก Student_tbl st <โดยที่> <Coelect> <เมื่อทดสอบ = "studentName! = null"> St.Student_name เช่น concat ('concat ('%' ! = null และ studentsex! = '' "> และ st.student_sex = #{studentsex, jdbctype = จำนวนเต็ม} </เมื่อ> <เมื่อทดสอบ =" studentbirthday! = null "> และ student_birthday = #{studentbirthday, jdbctype = date} และ st.class_id = #{classid, jdbctype = varchar} </เมื่อ> <เมื่อทดสอบ = "classEntity! = null และ classEntity.classId! = ''"> และ st.class_id = #{classEntity.classId, jdbctype = varchar} < #{placeid, jdbcType = varchar} </เมื่อ> <เมื่อทดสอบ = "placeentity! = null และ placeentity.placeid! = null และ placeentity.placeid! = ''"> และ St.Place_id = #{place.place.place.hplessid, jdbctype = varchar} < #{studentId, jdbcType = varchar} </เมื่อ> <อย่างอื่น> </อย่างอื่น> </เลือก> </where> </select>
หน้า
มันเป็นสิ่งจำเป็นมากสำหรับ SQL แบบไดนามิกส่วนใหญ่จะทำซ้ำผ่านคอลเลกชันโดยปกติจะอยู่ในสภาพ รายการอินสแตนซ์จะใช้คีย์ "รายการ" และอินสแตนซ์อาร์เรย์จะใช้คีย์ "อาร์เรย์" เป็นคีย์
องค์ประกอบ foreach นั้นมีประสิทธิภาพมากช่วยให้คุณระบุคอลเลกชันประกาศรายการคอลเลกชันและตัวแปรดัชนีซึ่งสามารถใช้ภายในร่างกายองค์ประกอบ นอกจากนี้ยังช่วยให้คุณระบุสตริงแบบเปิดและปิดวางตัวคั่นระหว่างการวนซ้ำ องค์ประกอบนี้ฉลาดมากและไม่ต่อท้ายตัวคั่นเพิ่มเติมโดยบังเอิญ
หมายเหตุ: คุณสามารถผ่านรายการอินสแตนซ์หรืออาร์เรย์เป็นวัตถุพารามิเตอร์ไปยัง mybatis เมื่อคุณทำสิ่งนี้ MyBatis จะห่อมันไว้ในแผนที่โดยอัตโนมัติด้วยชื่อเป็นคีย์ รายการอินสแตนซ์จะใช้คีย์ "รายการ" และอินสแตนซ์อาร์เรย์จะใช้คีย์ "อาร์เรย์" เป็นคีย์
ส่วนนี้ถูกกล่าวถึงเกี่ยวกับไฟล์การกำหนดค่า XML และไฟล์การแมป XML ส่วนถัดไปจะหารือเกี่ยวกับ Java API ในรายละเอียดเพื่อให้คุณได้รับการแมปที่มีประสิทธิภาพมากที่สุดที่คุณสร้างขึ้น
1. เขียนตัวอย่างของพารามิเตอร์เป็นอาร์เรย์
การประกาศวิธีการของอินเทอร์เฟซ:
รายการสาธารณะ <TudentEntity> getStudentListByClassIDS_FOREACH_ARRAY (String [] classIDS);
คำสั่ง SQL แบบไดนามิก:
<! -7.1 foreach (พารามิเตอร์อาร์เรย์วน) -เป็นเงื่อนไขสำหรับในที่ -> <select id = "getStudentListByClassIDS_FOREACH_ARRAY" resultMap = "resultMap_Studententity" SelectStudent_id, St.Student_name, St.Student_Sex จาก student_tbl st ที่ st.class_id ใน <foreach collection = "array" item = "classids" open = "(" separator = "," close = ")"> #{classids} </foreach>
ทดสอบรหัสเพื่อสอบถามนักเรียนในสองชั้นเรียนปี 20000001 และ 20000002:
@Test โมฆะสาธารณะ test7_Foreach () {string [] classIds = {"20000001", "20000002"}; รายการ <studentEntity> list = this.dynamicsqlmapper.getStudentListByClassIDS_FOREACH_ARRAY (ClassIDS); สำหรับ (studententity e: list) {system.out.println (e.toString ()); - 2. เขียนตัวอย่างของรายการพารามิเตอร์
การประกาศวิธีการของอินเทอร์เฟซ:
รายการสาธารณะ <TudentEntity> getStudentListByClassIDS_FOREACH_LIST (รายการ <String> ClassIDList);
คำสั่ง SQL แบบไดนามิก:
<!-7.2 foreach (รายการลูป <String> พารามิเตอร์)-เป็นเงื่อนไขสำหรับในสถานที่-> <select id = "getStudentListByClassIds_foreach_list" resultmap = "resultmap_studententity" SelectStudent_id, St.Student_name, St.Student_sex St.Place_id จาก Student_tbl ST โดยที่ St.Class_ID ใน <foreach Collection = "list" item = "classidList" open = "(" ตัวแยก = "," close = ")"> #{classidList} </foreach> </select>
ทดสอบรหัสเพื่อสอบถามนักเรียนในสองชั้นเรียนปี 20000001 และ 20000002:
@Test โมฆะสาธารณะทดสอบ 7_2_Foreach () {ArrayList <String> classIdList = new ArrayList <String> (); classidlist.add ("20000001"); classidlist.add ("200002"); รายการ <studentEntity> list = this.dynamicsqlmapper.getStudentListByclassIds_foreach_list (classidList); สำหรับ (studententity e: list) {system.out.println (e.toString ()); -3. ห่อหุ้มพารามิเตอร์ลงในประเภทของแผนที่ด้วยตัวเอง
<select id = "DynamicForEach3test" resultType = "blog"> เลือก * จาก t_blog โดยที่ชื่อ "%" #{title} "%" และ id ใน <foreach collection = "ids" index = "index" item = "item" open = "(" separator = "," close = ")"> #}ค่าของคอลเลกชันด้านบนคือ ID ซึ่งเป็นคีย์ของแผนที่พารามิเตอร์ที่ส่งผ่านและรหัส MAPPER ที่เกี่ยวข้อง:
รายการสาธารณะ <บล็อก> DynamicForEach3Test (แผนที่ <String, Object> Params);
รหัสทดสอบที่เกี่ยวข้อง:
@Test โมฆะสาธารณะ Public DynamicForEach3Test () {SQLSESSION SESSION = UTIL.GETSQLSessionFactory (). OpenSession (); BlogMapper BlogMapper = session.getMapper (BlogMapper.class); รายการสุดท้าย <integer> ids = new ArrayList <integer> (); ids.add (1); ids.add (2); ids.add (3); ids.add (6); ids.add (7); ids.add (9); แผนที่ <string, object> params = new hashmap <string, object> (); params.put ("ids", ids); params.put ("ชื่อ", "จีน"); รายการ <wlog> blogs = blogmapper.dynamicforeach3test (params); สำหรับ (บล็อกบล็อก: บล็อก) System.out.println (บล็อก); session.close (); -