MyBatis中 #{} 和 ${} 的區(qū)別小結(jié)
在MyBatis中,#{}
和${}
是兩種常見的占位符,它們的作用和使用場景有所不同。理解它們的區(qū)別對于正確使用MyBatis非常重要。
在Mybatis面試中常涉及到關(guān)于#{}和${}的區(qū)別
1、#{}是預編譯處理,$ {}是字符串替換。
2、MyBatis在處理#{}時,會將SQL中的#{}替換為?號,使用PreparedStatement的set方法來賦值;MyBatis在處理 $ { } 時,就是把 ${ } 替換成變量的值。
3、使用 #{} 可以有效的防止SQL注入,提高系統(tǒng)安全性。
1. #{} 和 ${} 的基本區(qū)別
#{}:SQL參數(shù)占位符
作用:#{}
用于將傳入的參數(shù)安全地綁定到SQL語句中,它會自動使用PreparedStatement
的?
占位符機制,并且MyBatis會對傳入的參數(shù)進行預處理(例如防止SQL注入)。
參數(shù)替換:在生成SQL語句時,#{}
會被替換為一個?
,然后由JDBC驅(qū)動程序?qū)?shù)值綁定到這個?
占位符上。
使用場景:通常用于傳遞用戶輸入的參數(shù),如查詢條件、插入或更新的數(shù)據(jù)等。
示例:
<select id="findUserById" resultType="User"> SELECT * FROM users WHERE id = #{id} </select>
如果傳入的
id
為1,MyBatis生成的SQL類似于:SELECT * FROM users WHERE id = ?
,然后通過PreparedStatement
將?
替換為1。
${}:SQL文本占位符
作用:${}
用于直接將傳入的參數(shù)值替換到SQL語句中,它不會進行預處理,因此直接將參數(shù)值插入到SQL語句中。這意味著${}
會將參數(shù)視為SQL的一部分,可能會導致SQL注入風險。
參數(shù)替換:在生成SQL語句時,${}
會直接將傳入的值替換到SQL語句中,而不會使用?
占位符。
使用場景:通常用于動態(tài)生成SQL片段,比如排序字段名、表名、列名等不直接來自用戶輸入的參數(shù)。
示例:
<select id="findUserByColumn" resultType="User"> SELECT * FROM users WHERE ${columnName} = #{value} </select>
如果傳入的
columnName
為username
,value
為John
,MyBatis生成的SQL類似于:SELECT * FROM users WHERE username = ?
,然后通過PreparedStatement
將?
替換為John
。
2. 安全性和使用建議
SQL注入防護:由于
#{}
會使用PreparedStatement
的參數(shù)綁定機制,因此可以有效防止SQL注入攻擊。而${}
直接將參數(shù)值拼接到SQL中,可能導致SQL注入,因此應(yīng)慎重使用。動態(tài)SQL生成:
${}
更適合用于生成動態(tài)的SQL片段,比如動態(tài)表名、列名等。但要確保傳入的值是可信任的,或者通過其他手段確保安全。
3. 具體示例
使用 #{} 的示例
<select id="findUserById" resultType="User"> SELECT * FROM users WHERE id = #{id} </select>
傳入id
為1,生成SQL為:
SELECT * FROM users WHERE id = ?
然后將參數(shù)1安全地綁定到?
上。
使用 ${} 的示例
<select id="findUserByColumn" resultType="User"> SELECT * FROM users WHERE ${columnName} = #{value} </select>
傳入columnName
為username
,value
為John
,生成SQL為:
SELECT * FROM users WHERE username = ?
然后將參數(shù)John
綁定到?
上。
SQL注入風險示例
<select id="findUserByColumn" resultType="User"> SELECT * FROM users WHERE ${columnName} = #{value} </select>
如果傳入的columnName
為username OR '1'='1'
,生成的SQL可能是:
SELECT * FROM users WHERE username OR '1'='1' = ?
這樣就可能導致SQL注入問題。
總結(jié)
#{}
:安全地傳遞參數(shù),防止SQL注入,常用于傳遞用戶輸入的參數(shù)。${}
:直接將參數(shù)值插入到SQL中,適用于動態(tài)生成SQL片段(如表名、列名),但存在SQL注入風險,應(yīng)謹慎使用。
在實際開發(fā)中,建議盡量使用#{}
來傳遞參數(shù),以確保SQL安全性,而對于使用${}
的場景,需要確保傳入的參數(shù)是安全且經(jīng)過驗證的。
到此這篇關(guān)于MyBatis中 /#{} 和 /${} 的區(qū)別小結(jié)的文章就介紹到這了,更多相關(guān)MyBatis /#{} 和 /${}內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MyBatis中#{}?和?${}?的區(qū)別和動態(tài)?SQL詳解
- mybatis中${}和#{}的區(qū)別以及底層原理分析
- MyBatis #{}和${} |與數(shù)據(jù)庫連接池使用詳解
- MyBatis中使用#{}和${}占位符傳遞參數(shù)的各種報錯信息處理方案
- Mybatis關(guān)于動態(tài)排序 #{} ${}問題
- mybatis中#{}和${}的區(qū)別詳解
- MyBatis中#{}和${}有哪些區(qū)別
- mybatis中${}和#{}取值的區(qū)別分析
- MyBatis中#{}占位符與${}拼接符的用法說明
- 詳解Mybatis中的 ${} 和 #{}區(qū)別與用法
- Mybatis之#{}與${}的區(qū)別使用詳解
- Mybatis中#{}與${}的區(qū)別詳解
相關(guān)文章
詳解SpringCloud eureka服務(wù)狀態(tài)監(jiān)聽
這篇文章主要介紹了詳解SpringCloud eureka服務(wù)狀態(tài)監(jiān)聽,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07Gradle build 報錯:Received status code 400 from server
這篇文章主要介紹了Gradle build 報錯:Received status code 400 from server,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07spring scheduled單線程和多線程使用過程中的大坑
本文主要介紹了spring scheduled單線程和多線程使用過程中的大坑,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01springmvc json類型轉(zhuǎn)換錯誤解決方案
這篇文章主要介紹了springmvc json類型轉(zhuǎn)換錯誤解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-12-12fastjson全局日期序列化設(shè)置導致JSONField失效問題解決方案
這篇文章主要介紹了fastjson通過代碼指定全局序列化返回時間格式,導致使用JSONField注解標注屬性的特殊日期返回格式失效問題的解決方案2023-01-01