目錄
一區別
二SQL${}注入問題
一區別
在MyBatis中,#{}和${}是兩種不同的參數占位符,用于在SQL語句中引用變量或參數。它們的區別如下:
1.#{}占位符(預編譯):#{}是MyBatis中的預編譯占位符,它會把傳入的參數值自動進行預編譯處理,以防止SQL注入攻擊。#{}占位符會將參數值作為一個占位符傳遞給數據庫驅動程序,驅動程序會將其轉化為一個預編譯的參數并進行安全處理,在執行SQL語句時,會將參數通過參數設置語句傳遞給數據庫。
2.${}占位符(字符串拼接):${}是Mybatis中的字符串拼接占位符,它會直接傳入的參數值拼接到SQL語句中。${}占位符會將參數值直接替換到生成的SQL語句中,這種方式比較靈活,可以動態拼接SQL語句的各個部分。
綜上所述,#{}占位符提供了更高的安全性,適合用于參數值的傳遞,而${}占位符具有更高的靈活性的,適合用于動態拼接SQL語句的各個部分,在使用占位符時,應根據具體的需求選擇合適的方式,并注意參數值的安全。
簡單來說#{}就是預編譯處理,${}是字符替換。
預編譯處理:是指MyBatis在處理的#{}時,就是把的#{}替換成了?號,使用PreparedStatement的set方法來賦值。也就是說#{}會把{}內的整體看成value,最后再給value加上單引號,重點強調引號內部是一個整體(#{}不會發生SQL注入的根本原因)。
二SQL${}注入問題
xml文件
<mapper namespace="com.caicode.dao.UserDao"><select id="query" resultType="com.caicode.entity.UserEntity">select * from user where sname = '${param1}' and spassword = '${param2}'</select>
</mapper>
?測試代碼
public static void main(String[] args) throws IOException {UserEntity userEntity = new UserService().queryOne("lisi","' or 1 = '1");System.out.println("登錄狀態:"+(userEntity == null?"失敗":"成功"));}
?sql最終的結果
select * from user where sname = 'Lisi' and spassword = '' or 1 = '1'
可以看到把符合結果的數據全部查詢出來了,總共11條
而正常來說我們的一般輸入是這樣的
public static void main(String[] args) throws IOException {UserEntity userEntity = new UserService().queryOne("zhangsan","123qwe");System.out.println("登錄狀態:"+(userEntity == null?"失敗":"成功"));}
?這樣輸入的話,最終的結果是一條。