Mabitis中#與$符號區別

上網看了好多博客,大多都一個意思,但是自己好像沒怎麼徹底理解具體原因,只是大概知道幾個點還是記下的,並未理解。

最後看到https://blog.csdn.net/qq_35978746/article/details/54944644算是明白了其中的道理;

總結下來就以下這麼幾點:

1:# 自己會帶有雙引號,$並不會

2:${ } 變量的替換階段是在動態 SQL 解析階段,而 #{ }在動態解析階段只是有個佔位符?,

      變量的替換是在 DBMS 中,所以#不會出現sql注入,所以能用#絕不用$

3:那具體啥時候使用#和$呢?

一般表名、或者不經常改變的字段,如排序就使用$;

注意:

Mapper.xml中如下的 sql 語句:
select * from user where name = #{name};  
動態解析爲:
select * from user where name = ?;  
一個 #{ } 被解析爲一個參數佔位符 ? 。
而${ } 僅僅爲一個純碎的 string 替換,在動態 SQL 解析階段將會進行變量替換。
例如,Mapper.xml中如下的 sql:
select * from user where name = ${name};  
當我們傳遞的參數爲 "Jack" 時,上述 sql 的解析爲:
select * from user where name = "Jack";  
預編譯之前的 SQL 語句已經不包含變量了,完全已經是常量數據了。
綜上所得, ${ } 變量的替換階段是在動態 SQL 解析階段,而 #{ }變量的替換是在 DBMS 中。

1、能使用 #{ } 的地方就用 #{ }
首先這是爲了性能考慮的,相同的預編譯 sql 可以重複利用。其次,${ } 在預編譯之前已經被變量替換了,這會存在 sql 注入問題。例如,如下的 sql:
select * from ${tableName} where name = #{name}  
假如,我們的參數 tableName 爲 user; delete user; --,那麼 SQL 動態解析階段之後,預編譯之前的 sql 將變爲:
select * from user; delete user; -- where name = ?;  
-- 之後的語句將作爲註釋,不起作用,因此本來的一條查詢語句偷偷的包含了一個刪除表數據的 SQL。
2. 表名作爲變量時,必須使用 ${ }
這是因爲,表名是字符串,使用 sql 佔位符替換字符串時會帶上單引號 '',這會導致 sql 語法錯誤,例如:
select * from #{tableName} where name = #{name};  
預編譯之後的sql 變爲:
select * from ? where name = ?;  
假設我們傳入的參數爲 tableName = "user" , name = "Jack",那麼在佔位符進行變量替換後,sql 語句變爲:
select * from 'user' where name='Jack';  
上述 sql 語句是存在語法錯誤的,表名不能加單引號 ''(注意,反引號 ``是可以的)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章