#{}與${}的區別
寫在前面:歡迎來到「發奮的小張」的博客。我是小張,一名普通的在校大學生。在學習之餘,用博客來記錄我學習過程中的點點滴滴,也希望我的博客能夠更給同樣熱愛學習熱愛技術的你們帶來收穫!希望大家多多關照,我們一起成長一起進步。也希望大家多多支持我鴨,喜歡我就給我一個關注吧!
首先,我們都知道。 #{}與 ${}都可以用來對SQL語句傳值。但默認情況下,我們都會採用第一種,使用#{}來傳值。那麼爲什麼不建議使用 ${} 呢。明明我用 ${}照樣可以執行SQL啊。
這裏我們要說一下,#{} 與 ${} 傳參的區別:
使用 #{} 傳入參數時,sql語句在解析過程中會加上 “”。
例如:
select * from user where name = #{name}
傳入值爲 name = 小張
此時在打印輸出一下SQL語句:
select * from table where name = ‘小張'
就是會當成字符串來解析。
而如果是使用${}傳入參數時,輸出的值就是當前值,不會附加" "。
還是以上面那個例子爲例吧!
select * from user where name = ${name}
傳入值爲 name = ‘小張’
此時在打印輸出一下SQL語句:
select * from user where name = '小張'
雖然都可以執行,也看不出什麼區別。那麼,我下面在舉一個例子吧!
假如我現在做一個用戶名密碼的登錄驗證,那麼我可以這樣寫SQL語句:
select *
from user
where username = ${username} and password = ${password}
此時,我給username和password分別傳入如下的值:
username = '1' or '1'='1' ;
password = '1' or '1'='1';
那麼,接下來將發生不得了的事情了。
此時打印輸出的SQL就是如下語句:
select *
from user
where username = '1' or '1'='1' and password = '1' or '1'='1'
這條語句等同於==>select * from user
相信大家都明白這條語句是什麼意思吧!
此時,這個登錄驗證已經無效了,無論怎麼查,只要數據庫有數據,都會成功!
這樣一對比,我們就知道了爲什麼使用#{}而儘量避免${}了。相比於 $ {} 的好處是比較明顯對的吧。 #{}傳參能防止sql注入,如果你傳入的參數爲 單引號’,那麼如果使用${},這種方式 那麼是會報錯的。
當然,${}也不是完全沒用的!
另外一種場景,如果你要做動態的排序,比如 order by column,這個時候務必要用${},因爲如果你使用了#{},那麼打印出來的將會是
select * from user order by 'name'
,這樣是沒用!
最後來一個小結吧!
小結:
1)#{}是預編譯處理,$ {}是字符串替換。
2)MyBatis在處理 #{} 時,會將SQL中的#{}替換爲?號,同時會使用PreparedStatement的set()方法來賦值;MyBatis在處理 $ { } 時,就是把 ${ } 替換成變量的值,因此會造成SQL語句的安全問題!
3)使用 #{} 可以有效的防止SQL注入,提高系統安全性。