區別:
(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注入
