ฉันใช้ Orm Framework MyBatis และฉันได้ใช้ฟังก์ชั่นทั่วไปใน mybatis วันนี้ในการพัฒนาโครงการมีธุรกิจที่ต้องการการ จำกัด ผู้ใช้จากฟิลด์การสืบค้นในตารางบางตารางและไม่ว่าจะมีฟิลด์บางอย่างเช่นฟิลด์บางอย่างในตารางบางแห่งไม่ได้รับอนุญาตให้สอบถามโดยผู้ใช้ ในกรณีนี้จำเป็นต้องสร้าง SQL ไปยังชื่อตารางและชื่อฟิลด์แบบไดนามิก ตอนนี้ฉันจะสรุปการแก้ปัญหาและฉันหวังว่ามันจะเป็นประโยชน์กับคู่ค้าของฉันที่พบปัญหาเดียวกัน
Dynamic SQL เป็นหนึ่งในคุณสมบัติที่ทรงพลังของ mybatis ก่อนที่คำสั่ง SQL ที่นำหน้า MyBatis จะแยกวิเคราะห์ SQL แบบไดนามิกและแยกวิเคราะห์ลงในวัตถุ BoundSQL ซึ่งถูกประมวลผลที่นี่ ก่อนอื่นมาทำความคุ้นเคยกับการใช้งาน #{} และ $ {} ใน mybatis:
ในกระบวนการแยกวิเคราะห์ SQL แบบไดนามิกเอฟเฟกต์ของ #{} และ $ {} แตกต่างกัน:
#{} แยกวิเคราะห์เป็นเครื่องหมายพารามิเตอร์สำหรับคำสั่ง jdbc preompiled
ดังที่แสดงในคำสั่ง SQL ต่อไปนี้
เลือก * จากผู้ใช้ที่ Name = #{ชื่อ};จะถูกแยกวิเคราะห์เป็น:
เลือก * จากผู้ใช้ที่ชื่อ =?;
คุณเห็น #{} ถูกแยกวิเคราะห์เป็นตัวยึดพารามิเตอร์หรือไม่? -
$ {} เป็นเพียงการเปลี่ยนสตริงบริสุทธิ์ การเปลี่ยนตัวแปรจะดำเนินการในระหว่างขั้นตอนการแยกวิเคราะห์ SQL แบบไดนามิกเช่นคำสั่ง SQL ต่อไปนี้:
เลือก * จากผู้ใช้ที่ชื่อ = $ {ชื่อ};เมื่อเราผ่านพารามิเตอร์ "Sprite" SQL จะแยกวิเคราะห์เป็น:
เลือก * จากผู้ใช้ที่ Name = "Sprite";
คุณจะเห็นได้ว่าคำสั่ง SQL ก่อนที่ precompilation จะไม่มีชื่อตัวแปรอีกต่อไป
โดยสรุปขั้นตอนการแทนที่ของตัวแปรของ $ {} อยู่ในขั้นตอนการแยกวิเคราะห์ SQL แบบไดนามิกในขณะที่การเปลี่ยนตัวแปรของ #{} อยู่ใน DBMS
ความแตกต่างระหว่าง #{} และ $ {} สามารถสรุปได้ง่าย ๆ ดังนี้:
#{} ปฏิบัติต่อพารามิเตอร์ที่ผ่านเป็นสตริงและเพิ่มคำพูดสองครั้งลงในพารามิเตอร์ที่ผ่าน
$ {} จะแสดงพารามิเตอร์ที่ผ่านโดยตรงใน SQL และจะไม่มีการเพิ่มใบเสนอราคา
#{} สามารถป้องกันการฉีด SQL ในเฉิงตู แต่ $ {} ไม่สามารถป้องกันการฉีด SQL
$ {} ถูกแทนที่ด้วยตัวแปรก่อนการ precompilation ซึ่งก่อให้เกิดความเสี่ยงของการฉีด SQL ดังนี้ SQL
เลือก * จาก $ {tablename} โดยที่ชื่อ = $ {ชื่อ}หากชื่อ tablename พารามิเตอร์ที่ผ่านเป็นผู้ใช้ ลบผู้ใช้; -หลังจากการแยกวิเคราะห์ SQL แบบไดนามิก SQL ก่อนที่การเปรียบเทียบจะกลายเป็น:
เลือก * จากผู้ใช้; ลบผู้ใช้; - ชื่อ =?;
-ข้อความที่ตามมาจะไม่ทำงานเป็นความคิดเห็นและเพื่อนของฉันและฉันก็ตกตะลึง! - - คุณเห็นหรือไม่ว่าคำสั่งแบบสอบถามต้นฉบับจริง ๆ แล้วมี SQL ที่ลบข้อมูลตารางซึ่งเป็นการลบลบลบ! - - ฉันพูดสิ่งสำคัญสามครั้งและคุณสามารถจินตนาการได้ว่าความเสี่ยงนั้นยิ่งใหญ่แค่ไหน
โดยทั่วไป $ {} ใช้ในการถ่ายโอนชื่อตารางชื่อฟิลด์ ฯลฯ ของฐานข้อมูล
พยายามอย่าใช้ $ {} ที่คุณสามารถใช้ #{}
ไปที่หัวข้อผ่านการวิเคราะห์ข้างต้นฉันเชื่อว่าคุณอาจมีความคิดบางอย่างเกี่ยวกับวิธีการเรียกชื่อตารางและชื่อฟิลด์แบบไดนามิก ตัวอย่างมีดังนี้:
<select id = "getUser" resultType = "java.util.map" parameterType = "java.lang.string" stementType = "คำสั่ง"> เลือก $ {คอลัมน์} จาก $ {tablename}ในการใช้ชื่อตารางการโทรแบบไดนามิกและชื่อฟิลด์ไม่สามารถใช้ precompilation ได้ คุณต้องเพิ่ม stementType = "คำสั่ง" "
คำแถลงการณ์: คำสั่งใด ๆ (ไม่คอมไพล์), เตรียม (precompiled) หรือ callable ซึ่งบอกให้ mybatis ใช้คำสั่ง, preparedstatement หรือ callablestatement ตามลำดับ ค่าเริ่มต้น: เตรียม เห็นได้ชัดว่าไม่สามารถใช้ precompilation ได้ที่นี่จะต้องเปลี่ยนเป็นไม่ได้ทำการคอมไพล์
ประการที่สองค่าของตัวแปรใน SQL คือ $ {xxx} ไม่ใช่ #{xxx}
เนื่องจาก $ {} คือการแสดงพารามิเตอร์ที่ส่งผ่านโดยตรงเพื่อสร้าง SQL ตัวอย่างเช่นพารามิเตอร์ที่ส่งผ่านใน $ {xxx} เป็นข้อมูลสตริงควรเพิ่มเครื่องหมายใบเสนอราคาก่อนที่พารามิเตอร์จะถูกส่งผ่านเช่น::
ชื่อสตริง = "Sprite"; name = "'" + ชื่อ + "'";
สรุป
ด้านบนเป็นวิธีแก้ปัญหาชื่อตารางการโทรและชื่อฟิลด์ MyBatis Dynamic ที่แนะนำโดยตัวแก้ไข ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!
บทความนี้ทำซ้ำจาก: http://www.yuanrengu.com/index.php/mybatis1021.html