MyBatis#{}與${}區別與動態傳入字段名問題解決

MyBatis動態傳入字段名


一、 #{}與${}區別

#{}:佔位符號,好處防止sql注入,相當於JDBC中的PreparedStatement
${}:是直接輸出變量的值

簡單說,#{}是經過預編譯的,是安全的;SQLorderby {},那麼不做任何處理的時候是存在SQL注入危險的。


二.、動態傳入字段名解決方案

通過以上對#{}${}符號的比較,可以很清楚的知道#{}可以防止sql注入,並且是預編譯的,所以想要動態傳入字段名、表名使用#{}是不行的,只有使用非預編譯的${}符號。

<select id="queryCar" resultType="CarsVo parameterType="java.util.Map">  
    SELECT
      *
    FROM
      cars c
    WHERE
      c. STATUS = #{status}
    ORDER BY
      #{sort} #{sort_type}
</select>

以上代碼使用#{sort}在進行動態參數傳入時,正如上文所講會發生錯誤,通過sort得到的參數值會先預編譯,從而不能實現傳入一個字段名。


通過上述講解,要想動態傳入字段名或表名,則要使用${}符號,直接取得傳來值。但是這樣一來就會存在sql注入的風險,所以就必須得手工防止sql注入。


三、防止sql注入

SQL注入是一種代碼注入技術,用於攻擊數據驅動的應用,惡意的SQL語句被插入到執行的實體字段中(例如,爲了轉儲數據庫內容給攻擊者)。

SQL注入,是一種常見的攻擊方式。攻擊者在界面的表單信息或URL上輸入一些奇怪的SQL片段(例如“and ‘2’=’2’”這樣的語句),從而入侵參數檢驗不足的應用程序。所以有必要在程序開發中,採用一些方式來防止該操作。在一些安全性要求很高的應用中(比如銀行軟件),經常使用將SQL語句全部替換爲存儲過程這樣的方式,來防止SQL注入。

MyBatis框架作爲一款半自動化的持久層框架,其SQL語句都要我們自己手動編寫,因此相當需要防止sql注入。


根據上文所講,#{}屬於預編譯,能夠防止sql注入,所以在編寫動態sql時,能使用#{}進行參數傳遞就儘量使用#{},如果不得已要使用${},就如動態傳入字段名,就必須得自己手工進行防止sql注入代碼的編寫。如判斷輸入參數的長度是否正常(注入語句一般很長),更精確的過濾則可以查詢一下輸入的參數是否在預期的參數集合中。
如:

 <!--判斷當前傳入參數長度是否如預期參數長度相同。-->
 <if test="sort.length == 'creat_time'.length">
    ${sort}
 </if>   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章