Mybatis---使用#{ }與${ }有什么區別?


#{}:表示一個占位符號,通過#{}可以實現preparedStatement向占位符中設置值,自動進行java類型和jdbc類型轉換,#{}可以有效防止sql注入。 #{}可以接收簡單類型值或pojo屬性值。

如果parameterType傳輸單個簡單類型值,#{}括號中可以是value或其它名稱。“%”#{name}”%”

${}:表示拼接sql串,通過${}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc類型轉換, ${}可以接收簡單類型值或pojo屬性值,

如果parameterType傳輸單個簡單類型值,${}括號中只能是value。

 

#{}是預編譯處理,$ {}是字符串替換。

預編譯的機制。預編譯是提前對SQL語句進行預編譯,而其后注入的參數將不會再進行SQL編譯。

我們知道,SQL注入是發生在編譯的過程中,因為惡意注入了某些特殊字符,最后被編譯成了惡意的執行操作。而預編譯機制則可以很好的防止SQL注入。

 

其實,區別就是如果使用#{},會將{}里面的傳入的值自動解析成為帶引號的值,比如:

select count(1) from tb_user where username = #{username} and  password  = #{password}

假如,此時傳入username傳入的值為admin,password傳入的值為123456,那么最后的sql就是:

select count(1) from tb_user where username = 'admin' and password  = '123456';

#{}會解析成字符串,而${}就會這樣解析:

select count(1) from t_user where username = admin and password  = 123456;

顯然,這是一個錯誤的sql語句,那么,什么叫SQL注入呢?為什么#{}可以有效的防止sql注入呢?

 

什么是SQL注入?

SQL注入就是利用現有應用程序,將(惡意)的SQL命令注入到后台數據庫執行一些惡意的操作

比如說,在登錄過程中,利用上面的語句到數據庫中查找用戶名/密碼是否存在,如果存在就登錄成功

而如果不存在就登錄失敗,如果說你后台使用的是${},惡意用戶在表單中的用戶名文本框中輸入的是'admin'

密碼框中輸入的是' ' or 1 = 1 加了一引號和一個恆成立的條件,那么,傳到數據庫中的sql就是:

select count(1) from t_user where user_name = 'admin' and user_password = ' ' or 1=1

如果程序沒有做其他的校驗,此時,該惡意用戶是可以登錄系統的! 這就是SQL注入,惡意攻擊

而如果使用#{}是不會出現這種情況的,#{}默認會給輸入的值加上引號,但是使用#{}在其他場景下並不適用

比如要使用到排序 order by #{} 傳入的參數應是表對應字段名,但是加上引號后就會解析成

order by 'age' 這樣就達不到排序的目的,而此時如果使用${}就可以達到排序的目的

即,sql解析成 order by age,根據age排序


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM