في بعض الأحيان ، هناك حاجة إلى بعض الحكم الأمني في شروط بيان SQL. على سبيل المثال ، إذا كانت المعلمة التي تم تمريرها فارغة عند الاستعلام وفقًا لشرط معين ، فمن المحتمل أن تكون نتيجة الاستعلام فارغة في هذا الوقت. ربما عندما نحتاج إلى أن تكون المعلمة فارغة ، سنجد جميع المعلومات. استخدم تسلسل Oracle ووظائف MySQL لإنشاء معرفات. في هذا الوقت يمكننا استخدام SQL الديناميكي. كل ما يلي هي بناء جملة MySQL والوظائف (مثل Concat وظيفة ارتباط السلسلة).
SELECTEY TAG
في عبارة INSERT ، يستخدم Oracle غالبًا تسلسلات ووظائف في MySQL لإنشاء المفتاح الأساسي لجدول الإدراج تلقائيًا ، ويلزم طريقة لإرجاع هذا المفتاح الأساسي الذي تم إنشاؤه. يمكن تحقيق هذا التأثير باستخدام علامة SelecteKey لـ MyBatis. المثال التالي هو استخدام وظيفة قاعدة بيانات MySQL NextVal ("الطالب") لإنشاء مفتاح وتعيينه على خاصية الطالب في فئة الكيانات التي تم تمريرها. لذلك بعد تنفيذ هذه الطريقة ، يمكن للحافة الحصول على المفتاح الذي تم إنشاؤه من خلال فئة الكيان هذه.
<!-أدخل المفتاح الأساسي التلقائي للطلاب-> <insert id = "createStudentAutokey" parametertype = "liming.student.manager.data.model.studententity" keyproperty = "studentId"> <selectekey keyproperty = "studentId" resulttype = "strup". student_tbl (student_id ، student_name ، student_sex ، student_birthday ، student_photo ، class_id ، place_id) القيم ( #{tudentId} ، #{studentName} ، #{studentsex} ، #{studentbirthday} ، #{{judtepe ، javatype = typeHandler = org.apache.ibatis.type.blobtypehandler} ، #{classid} ، #{placeid}) </sert>
استدعاء طرق واجهة والحصول على توليد مفاتيح تلقائي
كيان الطالب = طالب جديد () ؛ entity.setStudentName ("Hello Dawn") ؛ entity.setStudentSex (1) ؛ entity.SetStudentBirthday (DateUtil.Parse ("1985-05-28")) ؛ entity.setClassid ("20000001") ؛ entity.setplaceid ("70000001") ؛ this.dynamicsqlmapper.createstudentautokey (الكيان) ؛ System.out.println ("معرف الطالب الجديد:" + entity.getStudentId ()) ؛
SELECTEKEKEY تفاصيل تكوين خاصية بيان:
| ملكية | يصف | احصل على القيمة |
| KeyProperty | السمة التي يجب تعيينها للنتيجة التي تم إنشاؤها بواسطة عبارة SELECTEKEY. | |
| النتيجة | توليد أنواع النتائج. يتيح MyBatis استخدام أنواع البيانات الأساسية ، بما في ذلك أنواع السلسلة وأنتي. | |
| طلب | 1: قبل ذلك ، سيتم تحديد المفتاح الأساسي أولاً ، ثم سيتم تعيين keyproperty ، ثم سيتم تنفيذ عبارة INSERT ؛ 2: بعد ، قم بتشغيل عبارة إدراج أولاً ثم بيان SELECTEKEY. | قبل بعد |
| بيان stateTytype | يدعم MyBatis البيان ، نماذج بيان مستعدة وقابلة للاستدعاء ، المقابلة للبيان ، استجابات الجهة المعدلة والاستجابات. | إفادة مُعد قابلية للتطبيق |
إذا كانت العلامة
إذا كان يمكن استخدام العلامات في العديد من أنواع عبارات SQL ، فلنأخذ الاستعلام كمثال. أولاً ، دعونا نلقي نظرة على استعلام عادي للغاية:
<!-قائمة طالب الاستعلام ، مثل الاسم-> <تحديد ID = "getStudentListLikEname" parametertype = "studententity" resultmap = "studentResultMap"> حدد * من student_tbl st حيث st.Student_name مثل concat ('٪' ، #{{}}) ، '٪') ومع ذلك ، إذا كان اسم الطالب أو الطالب فارغًا في هذا الوقت ، فمن المحتمل أن يبلغ هذا البيان عن خطأ أو أن تكون نتيجة الاستعلام فارغة. في هذا الوقت ، نستخدم بيان SQL الديناميكي لإصدار الأحكام أولاً. إذا كانت القيمة لاغية أو تساوي سلسلة فارغة ، فلن نصدر أحكامًا على هذا الشرط وزيادة المرونة.
المعلمة هي طالب فئة الكيان. يتم الحكم على جميع السمات في فئة الكيان ، وإذا لم تكن فارغة ، يتم تنفيذ حالة الحكم.
<!-2 إذا (معلمة الحكم)-استخدم الخاصية التي لا تكون فئة الكيان فارغة كشرط-> <select id = "getStudentList_if" resultmap = "resultMap_Studentity" parametertype = "liming.student.manager.data.model.Studententity" St.Student_Birthday ، St.Student_photo ، St.Class_id ، St.Place_id من student_tbl st حيث <if test = "studentName! = null"> st.Student_Name مثل concat ('٪' ، #{studentName ، jdbctype = varchar}) ، '٪') "> و st.Student_Sex = #{studentSex ، jdbctype = integer} </fort> <if test =" studentbirthday! = null "> و St.Student_BirthDay = #{{{{{chaterbirthday ، jdbctype = date} </if> if test =" classid! = " #{classid ، jdbctype = varchar} </if> <if test = "classentity! = null and classentity.classid! = null and classentity.classid! = ''" St.Place_ID = #{placeId ، jdbctype = varchar} </far> <if test = "placeentity! = null and placeentity.placeid! = null and placeentity.placeid! = ''"> و st.Id_id = #{placeentity.placeid ، jdbctype = varchar} St.Student_id = #{studentId ، jdbctype = varchar} </if> </reveld>عند استخدامه ، إذا كنت ترغب في استخدامه ، فأنت بحاجة إلى الحد من حالة فئة الكيان الجديدة. تحتاج فقط إلى إرفاق القيمة المقابلة إلى مكان الشرط. على العكس من ذلك ، إذا لم تقم بتعيين القيمة ، فلا يمكنك الحكم على مكان.
public void select_test_2_1 () {studententity ictity = new Studententity () ؛ entity.setStudentName ("") ؛ entity.setStudentSex (1) ؛ entity.SetStudentBirthday (DateUtil.Parse ("1985-05-28")) ؛ entity.setClassid ("20000001") ؛ //entity.setplaceid("70000001 ") ؛ قائمة <Tudententity> list = this.dynamicsqlmapper.getStudentList_if (الكيان) ؛ لـ (studententity e: list) {system.out.println (e.ToString ()) ؛ }}
إذا + حيث الحكم الشرطي
قد تتسبب هذه المجموعات في حدوث أخطاء عندما تستخدم المزيد من العلامات. دعنا نأخذ بيان الاستعلام في 3.1 كمثال ، عندما يسمى رمز Java على النحو التالي:
test public void select_test_2_1 () {studententity intity = new StudentIty () ؛ entity.setStudentName (null) ؛ entity.setStudentSex (1) ؛ قائمة <Tudententity> list = this.dynamicsqlmapper.getStudentList_if (الكيان) ؛ لـ (studententity e: list) {system.out.println (e.ToString ()) ؛ }} إذا كان المثال أعلاه فارغًا ، فلن يتم الحكم على عمود student_name ، وسيتم اشتقاق الخطأ الإضافي لـ "WHERE و" WHERE ".
في هذا الوقت ، يمكننا استخدام حيث البيانات الديناميكية لحل المشكلة. ستعرف علامة "أين" أنه إذا كانت العلامة التي تحتوي عليها لها قيمة إرجاع ، فسيتم إدراجها "حيث". بالإضافة إلى ذلك ، إذا بدأ المحتوى الذي يتم إرجاعه بواسطة علامة مع أو أو ستتم إزالته.
يتم تعديل المثال أعلاه إلى:
<!- 3 SELECT- WHERE/IF (معلمة الحكم)- استخدم الخاصية التي لا تكون فئة الكيان فارغة كشرط-> <SELECT ID = "getStudentList_where" resultmap = "resultmap_studententity" parametertype = "liming.student.manager.data.model.StudentIntity" St.Student_Birthday ، St.Student_photo ، St.Class_ID ، St.Place_id من student_tbl st <where> <if test = "studentName! = null"> st.Student_Name مثل concat ('٪' ، #{studentName ، jdbctype = varchar}) ، '٪') "" "> و st.Student_sex = #{studentSex ، jdbctype = integer} </if> <if test =" studentbirthday! = null "> و st.Student_BirthDay = #{{classidded! #{classid ، jdbctype = varchar} </if> <if test = "classentity! = null and classentity.classid! = ''"> و st.class_id = #{classentity.classid ، jdbctype = varchar} </if> if test = "placeid! = null و placeid! jdbctype = varchar} </if> <if test = "placeentity! = null and placeentity.placeid! = null and placeentity.placeid! = ''"> و st.place_id = #{placeentity.placeId ، jdbctype = varchar} </if> if = jdbctype = varchar} </if> </where> </select> بيان التحديث لـ if + set
عندما لا يتم استخدام العلامة IF في عبارة التحديث ، إذا كان هناك معلمة فارغة ، فسيؤدي ذلك إلى حدوث خطأ.
عند استخدام علامات في عبارات التحديث ، إذا لم يتم تنفيذ ما إذا لم يتم تنفيذه ، فقد يؤدي ذلك إلى خطأ زائد فاصلة. استخدم علامة SET لتكوين الكلمات الرئيسية SET بشكل ديناميكي ولإزالة أي فاصل غير مرتبط بإلحاقه بنهاية الشرط.
بعد التعديل مع علامة if+set ، إذا كان عنصرًا فارغًا ، فلن يتم تحديثه ، ولكن سيتم الحفاظ على قيمة قاعدة البيانات الأصلية. المثال التالي:
<!-4 if/set (معلمة الحكم)-تحديث سمات فئة الكيان التي ليست فارغة-> <update id = "updatestudent_if_set" parametertype = "liming.student.manager.data.model.Studententity"> تحديث student_tbl <set> <s test = "test =" null! #{StudentName} ، </if> <if test = "studentSex! = null و studentSex! = ''"> student_tbl.student_sex = #{studentSex} ، </if> <test = "studentbirthday! = null"> student_tbl.student_birthday = { ) ! = '' ''> student_tbl.place_id = #{placeid} </fort> </st> حيث student_tbl.student_id = #{studentId} ؛ </uptuday> إذا + تقليم بدلاً من مكان/تعيين العلامة
يعد Trim مكانًا أكثر مرونة للذهاب إلى علامات الكلمات الرئيسية المتكررة ، والتي يمكن أن تمارس تأثيرات مكان وضعه.
تقليم بدلا من أين
<!-5.1 إذا كان/trim يستبدل مكان (معلمة الحكم)-استخدم السمات التي لا تكون فئة الكيان فيها فارغة كشرط-> <SELECT ID = "GetStudentList_if_trim" resultMap = "resultMap_Studentity"> Select St.Student_id ، St.Stclass_name ، st.Student_Sex ، St.Birth. من student_tbl st <trim prepix = "where" prefixOverRides = "و | أو"> <> <test = "studentName! = null"> st.Student_name مثل concat (concat ('٪' ، #{studentname ، jdbctype = varchar}) ، '٪') #{{studentSex ، jdbctype = integer} </if> <if test = "studentbirthday! = null"> و st.Student_birthday = #{studentbirthday ، jdbctype = date} </if> <classid! = null و classid! = '' jdbctype = varchar} </if> <if test = "classentity! = null و classentity.classid! = null و classentity.classid! = ''"> و st.class_id = #{classentity.classid ، jdbctype = varchar} </if> </ #{placeId ، jdbctype = varchar} </If> <if test = "placeentity! = null and placeentity.placeid! = null and placeentity.placeid! = ''"> و st.place_id = #{placeentity.placeid ، jdbctype = varchar} </إذا #{studentId ، jdbctype = varchar} </if> </rim> </rection>
تقليم بدلا من المجموعة
<!-5.2 if/trim استبدال SET (معلمة الحكم)-تحديث سمات فئة الكيان التي ليست فارغة-> <update id = "updatestudent_if_trim" parametertype = "liming.student.manager.data.model.studententity" ! = '' '"> student_tbl.student_name = #{{studentName} ، </if> <if test =" studentsex! = null و studentSex! =' '' '> student_tbl.student_sex = #{{{studentsex} ، </if> <s test = #{StudentBirthday} ، </if> <if test = "studentPhoto! = null"> student_tbl.student_photo = #{studentphoto ، javatype = byte [] ، jdbctype = blob ، typehandler = org.apache.ibatis.type.blobte. student_tbl.class_id = #{classId} ، </if> <if test = "placeid! = ''"> student_tbl.place_id = #{placeid} </if> </rim> where student_tbl.student_id = #{{} </update> اختر (عندما ، خلاف ذلك)
في بعض الأحيان لا نريد تطبيق جميع الشروط ، ولكن فقط اختر خيارًا من خيارات متعددة. عند استخدام علامة if ، طالما أن التعبير في الاختبار صحيح ، سيتم تنفيذ الشروط الموجودة في العلامة IF. يوفر MyBatis عنصر الاختيار. إذا كانت العلامة علاقة بـ (و) ، واختيار علاقة مع (أو).
تتمثل علامة الاختيار في تحديد ما إذا كانت شرط الاختبار بالداخلية عندما تكون العلامة صالحة بالترتيب. إذا كان المرء صالحًا ، ينتهي الاختيار. عندما لا تكون جميع الشروط في الاختيار غير راضية ، يتم تنفيذ SQL في خلاف ذلك. على غرار عبارة Switch's Java ، اختر Switch ، عند الحالة ، وإلى الافتراضي.
على سبيل المثال ، تدوين الأمثلة التالية أيضًا جميع الشروط التي يمكن تقييدها واستخدامها. SELECT سيختار تنفيذ SQL مع اختبار TRUE من أعلى إلى أسفل عندما العلامة. لاعتبارات الأمان ، نستخدم مكان اختتام الاختيار ووضع كلمات رئيسية أكثر من الأخطاء.
<!-6-اختر (معلمات الحكم)-خذ أول خاصية لفئة الكيان غير فارغة بالترتيب عند الشرط-> <select id = "getStudentList_Choose" resultMap = "resultMap_StudentIntity" parametertype = "liming.student.manager.data.model.studententity St.Student_sex ، St.Student_birthday ، St.Student_photo ، St.Class_ID ، St.Place_id من student_tbl st <Where> <rection> <at test = "studentName! = null"> st.Student_name مثل concat ('٪' ، #{{jdbctype = vareChar}) ! = null و studentSex! = '' ''> و st.Student_sex = #{studentSex ، jdbctype = integer} </nhen> <at test = "studentbirth! و st.class_id = #{classid ، jdbctype = varchar} </عندما> <عندما test = "classentity! = null و classentity.classid! = ''"> و st.class_id = #{classentity.classid ، jdbctype = varchar} </when> end = #{placeId ، jdbctype = varchar} </at> <عندما test = "placeentity! = null و placeentity.placeid! = null و placeentity.placeid! = ''"> و st.place_id = #{placeentity.placeid ، jdbctype = varchar} </عندما> #{studentId ، jdbctype = varchar} </hen> <rolly> </romeal> </search> </where> </rection>
foreach
من الضروري للغاية لـ SQL الديناميكي ، وخاصة للتكرار على مجموعة ، عادة في الظروف. ستستخدم مثيلات القائمة "قائمة" كمفتاح ، وستستخدم مثيلات الصفيف "Array" كمفتاح.
عنصر foreach قوي للغاية ، ويسمح لك بتحديد مجموعة وإعلان عناصر التجميع ومتغيرات الفهرس ، والتي يمكن استخدامها داخل هيئة العناصر. كما يتيح لك تحديد السلاسل المفتوحة والمغلقة ، ووضع الفواصل بين التكرارات. هذا العنصر ذكي للغاية ، ولا يعرض فواصل إضافية عن طريق الصدفة.
ملاحظة: يمكنك تمرير مثيل القائمة أو الصفيف ككائن معلمة إلى MyBatis. عند القيام بذلك ، سيقوم MyBatis تلقائيًا بلفه في خريطة مع الاسم كمفتاح. ستستخدم مثيلات القائمة "قائمة" كمفتاح ، وستستخدم مثيلات الصفيف "Array" كمفتاح.
تمت مناقشة هذا القسم حول ملفات تكوين XML وملفات رسم الخرائط XML. سيناقش القسم التالي واجهة برمجة تطبيقات Java بالتفصيل ، حتى تتمكن من الحصول على أكثر التعيينات فعالية التي أنشأتها.
1. اكتب مثال المعلمة كصفيف
إعلان طريقة الواجهة:
القائمة العامة <Tudententity> getStudentListbyClassids_foreach_array (سلسلة [] classids) ؛
بيان SQL الديناميكي:
<! student_tbl st where st.class_id in <foreach collection = "array" item = "classids" open = "(" separator = "،" close = ")
اختبر الرمز للاستعلام عن الطلاب في الفصلين من 20000001 و 20000002:
test public void test7_foreach () {string [] classids = {"20000001" ، "20000002"} ؛ قائمة <Tudententity> 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_studentity"> حدد st.Student_id ، st.Student_name ، st.Student_Sex ، student_tbl st where st.class_id in <foreach collection = "list" item = "classIdList" open = "(" separator = "،" close = ")
اختبر الرمز للاستعلام عن الطلاب في الفصلين من 20000001 و 20000002:
test public void test7_2_foreach () {ArrayList <String> classIdList = جديد ArrayList <String> () ؛ ClassIdList.add ("20000001") ؛ ClassIdList.add ("20000002") ؛ قائمة <Tudententity> list = this.dynamicsqlmapper.getStudentListByClassids_foreach_list (classIdList) ؛ لـ (studententity e: list) {system.out.println (e.ToString ()) ؛ }}3. قم بتغليف المعلمات في نوع الخريطة بنفسك
<select id = "dynamicforeach3test" resulttype = "blog"> select * from t_blog حيث عنوان مثل "٪" #{title} "٪" و id في <foreach collection = "ids" index = "index" = "item =" ("expens =" ("firedator =" ، "elation =")قيمة المجموعة أعلاه هي IDS ، وهي مفتاح خريطة المعلمة التي تم تمريرها ، ورمز الخريطة المقابل:
القائمة العامة <log> dynamicforeach3test (خريطة <سلسلة ، كائن> params) ؛
رمز الاختبار المقابل:
test public void 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 ("title" ، "China") ؛ قائمة <Nog> blogs = blogmapper.dynamicforeach3test (params) ؛ لـ (Blog Blog: Blogs) System.out.println (Blog) ؛ session.close () ؛ }