區別: (1)#將傳入的數據都當成一個字元串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,如果傳入的值是id,則解析成的sql為order by "id"。 (2)$將傳入的數據直接顯示生成在sql中。如:order by $user_id$,如果傳入的值是id,則解析 ...
區別:
(1)#將傳入的數據都當成一個字元串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,如果傳入的值是id,則解析成的sql為order by "id"。
(2)$將傳入的數據直接顯示生成在sql中。如:order by $user_id$,如果傳入的值是id,則解析成的sql為order by id。
(3)#方式在很大程度上能夠防止sql註入。
(4)$方式無法防止sql註入。
(5)$方式一般用於傳入資料庫對象,例如傳入表名。(這裡得註意SQL註入問題)
(6)一般能用#的就別用$。
ps:在使用mybatis中還遇到<![CDATA[]]>的用法,在該符號內的語句,將不會被當成字元串來處理,而是直接當成sql語句,比如要執行一個存儲過程。
總結區別:#{} 傳入值時,sql解析時,參數是帶引號的,而${}穿入值,sql解析時,參數是不帶引號的。
舉個例子:
select * from ${table_Name} where name = #{name}
在這個例子中,如果表名為
user; delete user; --
則動態解析之後 sql 如下:
select * from user; delete
user; -- where name = ?;
--之後的語句被註釋掉,而原本查詢用戶的語句變成了查詢所有用戶信息+刪除用戶表的語句,會對資料庫造成致命損傷。
但是表名用參數傳遞進來的時候,只能使用 ${} 。這也提醒在這種用法中要小心sql註入的問題。
防止SQL註入方法:
首先,永遠不要相信用戶的輸入。
(1)不使用SQL,考慮NoSQL。
(2)正則表達式,字元串過濾。
(3)參數綁定PreparedStatement。
(4)使用正則表達式過濾傳入的參數。
(5)JSP中調用該函數檢查是否包函非法字元或JSP頁面判斷代碼。JSP參考JSP使用過濾器防止SQL註入