# {}與${}的區(qū)別
默認情況下,使用#{}語法,MyBatis會產(chǎn)生PreparedStatement語句中,并且安全的設置PreparedStatement參數(shù),這個過程中MyBatis會進行必要的安全檢查和轉義。
示例1:
執(zhí)行SQL:Select * from user where name = #{name}
參數(shù):name=>xin
解析后執(zhí)行的SQL:Select * from user where name = ?
執(zhí)行SQL:Select * from user where name = ${name}
參數(shù):name:ke
解析后執(zhí)行的SQL:Select * from user where name =ke
說明:
#將傳入的數(shù)據(jù)都當成一個字符串,會對自動傳入的數(shù)據(jù)加一個雙引號。如:order by #{user_id},如果傳入的值是 name , 那么解析成sql時的值為order by “name”, 如果傳入的值是id,則解析成的sql為order by “id”.$將傳入的數(shù)據(jù)直接顯示生成在sql中。如:order by ${user_id},如果傳入的值是name, 那么解析成sql時的值為order by name, 如果傳入的值是id,則解析成的sql為order by id.
綜上所述,$ {}方式會引發(fā)SQL注入的問題、同時也會影響SQL語句的預編譯,所以從安全性和性能的角度出發(fā),能使用#{}的情況下就不要使用 ${}。
${} 在什么情況下使用呢?
有時候可能需要直接插入一個不做任何修改的字符串到SQL語句中。這時候應該使用${}語法。
比如,動態(tài)SQL中的字段名,如:ORDER BY ${columnName}
<select id="queryMetaList" resultType="Map">
Select * from name where name = ${name} ORDER BY ${age}
</select>
由于${}僅僅是簡單的取值,所以以前sql注入的方法適用此處,如果我們order by語句后用了${},那么不做任何處理的時候是存在sql注入危險的。