面試問題:持久層框架Mybatis中#{}與${}的區別

#{}與${}的區別

寫在前面:歡迎來到「發奮的小張」的博客。我是小張,一名普通的在校大學生。在學習之餘,用博客來記錄我學習過程中的點點滴滴,也希望我的博客能夠更給同樣熱愛學習熱愛技術的你們帶來收穫!希望大家多多關照,我們一起成長一起進步。也希望大家多多支持我鴨,喜歡我就給我一個關注吧!

在這裏插入圖片描述

首先,我們都知道。 #{} ${}都可以用來對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注入,提高系統安全性

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