搜了一晚上,原諒我的愚蠢:這里sql中占位符#{},${} 是JDBC提供使用的,跟什么Ognl表達式,EL表達式或者jstl標簽庫完全沒關系!
#將傳入的數據都當成一個字符串,會對自動傳入的數據加一個雙引號。如:order by #user_id#,如果傳入的值是111,那么解析成sql時的值為order by “111”, 如果傳入的值是id,則解析成的sql為order by “id”。
$將傳入的數據直接顯示生成在sql中。如:order by userid,如果傳入的值是111,那么解析成sql時的值為order by user_id, 如果傳入的值是id,則解析成的sql為order by id。
#方式能夠很大程度防止sql注入;$方式無法防止Sql注入。
$方式一般用於傳入數據庫對象,例如傳入表名。
一般能用#的就別用$。MyBatis排序時使用order by 動態參數時需要注意,用$而不是#。
默認情況下,使用#{}格式的語法會導致MyBatis創建預處理語句屬性並以它為背景設置安全的值(比如?)。這樣做很安全,很迅速也是首選做法,有時你只是想直接在SQL語句中插入一個不改變的字符串。比如,像ORDER BY,你可以這樣來使用:
ORDER BY ${columnName};
- 1
- 2
這里MyBatis不會修改或轉義字符串。
重要:接受從用戶輸出的內容並提供給語句中不變的字符串,這樣做是不安全的。這會導致潛在的SQL注入攻擊,因此你不應該允許用戶輸入這些字段,或者通常自行轉義並檢查。
-------------------------------------------------------------------
sql語句中的#{}
例:Student stu = new Student("田七",27,95);
Map<String,Object> map=new HashMap<String, Object>();
map.put("nameCon", "張");
map.put("ageCon", 23);
map.put("stu", stu);
select id,name,age,score from student where name like '%' #{nameCon} '%' and age > #{ageCon} and score > #{stu.score}
#{}中可以放什么內容:
1)參數對象的屬性
2)隨意內容,此時的#{}是個占位符
3)參數為map時的key
4)參數為map時,若key對應的value為對象,則可將該對象的屬性放入
5)參數的索引號
---------------------------------------------------------
sql語句中使用#跟$的區別(MyBatis中)
$不進行數據類型匹配,$變量名$就直接把 $name$替換為 name的內容
例如:
select * from tablename where id = #id# ,假設id的值為12,其中如果數據庫字段id為字符型,那么#id#表示的就是'12',如果id為整型,那么#id#就是 12
會轉化為jdbc的 select * from tablename where id=?,把?參數設置為id的值
select * from tablename where id = $id$ ,如果字段id為整型,Sql語句就不會出錯,但是如果字段id為字符型,
那么Sql語句應該寫成 select * from table where id = '$id$'
3、#方式能夠很大程度防止sql注入.
4、$方式無法方式sql注入.
5、$方式一般用於傳入數據庫對象.例如傳入表名.
6、所以ibatis用#比$好,一般能用#的就別用$.
另外,使用##可以指定參數對應數據庫的類型
如:
select * from tablename where id = #id:number#
在做in,like 操作時候要特別注意
總結以下:
$號使用在具體pojo類也就是非基本類型的取值,而#號使用在具體有基本類型的取值