1. 程式人生 > >使用拼接符還是佔位符——由Mybatis排序無效問題的延伸

使用拼接符還是佔位符——由Mybatis排序無效問題的延伸

使用拼接符還是佔位符?

佔位符#相比於拼接符$最大的區別就是能防止SQL注入,所以原則上應該儘可能的使用#而不是$,那麼應該在什麼情況下使用$

由這個經典的order by 問題引出

在sql裡,任意一句select 語句加上order by 關鍵字 (或是已有order by關鍵字),然後加上'dafafadfagdghfdc 23423'或者是 '' 或者是 23141234或者再加一個, ''這樣亂七八糟的引數是不影響sql的’正常執行’的,這意味著什麼?意味著如果order by 後跟的是一個引數,那麼如果引數和關鍵字都被引號給包住,那麼無論是引數還是關鍵字都不起任何作用,而且不會報任何錯誤,例如

注意程式碼高亮
order by "id desc"
-- 而不是
order by id desc

想要排序的一定是某個或者多個欄位,那麼

涉及到欄位名傳參的時候就不能使用#,而得使用$
僅僅是欄位值引數的傳遞,需要使用#

需要保持良好習慣的是,即使是用拼接符,在涉及到傳值的時候,也手動為引數兩邊加引號,防止下面這種型別的注入

WHERE U_account = 'xxxxxx or 1=1 -- ' 

參考

mybatis中order by排序無效問題|

  1. #將傳入的資料都當成一個字串,會對自動傳入的資料加一個雙引號。如:order by #{user_id}
    ,如果傳入的值是111,那麼解析成sql時的值為order by "111", 如果傳入的值是id,則解析成的sql為order by "id"
  2. $將傳入的資料直接顯示生成在sql中。如:order by ${user_id},如果傳入的值是111,那麼解析成sql時的值為order by 111, 如果傳入的值是id,則解析成的sql為order by id
  3. #方式能夠很大程度防止sql注入。
  4. $方式無法防止Sql注入。
  5. $方式一般用於傳入資料庫物件,例如傳入表名。
  6. 一般能用#的就別用$

ps: 在使用mybatis中還遇到<![CDATA[]]>的用法,在該符號內的語句,將不會被當成字串來處理,而是直接當成sql語句,比如要執行一個儲存過程。