#{xxx},使用的是PreparedStatement,會有類型轉換,因此比較安全;sql
${xxx},使用字符串拼接,能夠SQL注入;安全
like查詢不當心會有漏動,正確寫法以下:mybatis
Mysql: select * from t_user where name like concat('%', #{name}, '%') spa
Oracle: select * from t_user where name like '%' || #{name} || '%' 日誌
SQLServer: select * from t_user where name like '%' + #{name} + '%'orm
關於上述結論能夠在xml中驗證xml
一、select * from test where id = #{id}對象
隨便傳個id執行後能夠在日誌中看到以下結果字符串
select * from test where id = ?編譯
原理是採用了jdbc中的PreparedStatement,PreparedStatement是咱們很熟悉的Statement的子類,它的對象包含了編譯好的sql語句。這種「準備好」的方式不只能提升安全性,並且在屢次執行一個sql時,可以提升效率,緣由是sql已編譯好,再次執行時無需再編譯。
二、select * from test order by ${list}
隨便傳個參數例如id執行後能夠在日誌中看到以下結果
select * from test order by id
這種是字符串拼接的,存在sql注入隱患
在mybatis中,」${xxx}」這樣格式的參數會直接參與sql編譯,從而不能避免注入攻擊。但涉及到動態表名和列名時,只能使用「${xxx}」這樣的參數格式,因此,這樣的參數須要咱們在代碼中手工進行處理來防止注入。
因此儘可能用#{}這種方式傳參數,若是用到了${}方式要手動過濾sql注入。