MyBatis中 #{} 和 ${} 的區(qū)別小結
在MyBatis中,#{}和${}是兩種常見的占位符,它們的作用和使用場景有所不同。理解它們的區(qū)別對于正確使用MyBatis非常重要。
在Mybatis面試中常涉及到關于#{}和${}的區(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驅動程序將參數(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注入,因此應慎重使用。動態(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注入問題。
總結
#{}:安全地傳遞參數(shù),防止SQL注入,常用于傳遞用戶輸入的參數(shù)。${}:直接將參數(shù)值插入到SQL中,適用于動態(tài)生成SQL片段(如表名、列名),但存在SQL注入風險,應謹慎使用。
在實際開發(fā)中,建議盡量使用#{}來傳遞參數(shù),以確保SQL安全性,而對于使用${}的場景,需要確保傳入的參數(shù)是安全且經過驗證的。
到此這篇關于MyBatis中 /#{} 和 /${} 的區(qū)別小結的文章就介紹到這了,更多相關MyBatis /#{} 和 /${}內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
使用Spring Framework 時常犯的十大錯誤(小結)
這篇文章主要介紹了使用Spring Framework 時常犯的十大錯誤(小結),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-07-07
為什么Spring官方推薦的@Transational還能導致生產事故
在Spring中進行事務管理非常簡單,只需要在方法上加上注解@Transactional,那么為什么Spring官方推薦的@Transational還能導致生產事故,本文就詳細的介紹一下2021-11-11
Java基于SpringBoot和tk.mybatis實現(xiàn)事務讀寫分離代碼實例
這篇文章主要介紹了Java基于SpringBoot和tk.mybatis實現(xiàn)事務讀寫分離代碼實例,讀寫分離,基本的原理是讓主數(shù)據(jù)庫處理事務性增、改、刪操作,而從數(shù)據(jù)庫處理SELECT查詢操作,數(shù)據(jù)庫復制被用來把事務性操作導致的變更同步到集群中的從數(shù)據(jù)庫,需要的朋友可以參考下2023-10-10
spring aop action中驗證用戶登錄狀態(tài)的實例代碼
本篇文章主要介紹了spring aop action中驗證用戶登錄狀態(tài)的實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07

