MyBatis動態傳入字段名
一、 #{}與${}區別
#{}:佔位符號,好處防止sql注入,相當於JDBC中的PreparedStatement
${}:是直接輸出變量的值
簡單說,#{}是經過預編譯的,是安全的;
二.、動態傳入字段名解決方案
通過以上對#{}
和${}
符號的比較,可以很清楚的知道#{}可以防止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>