MyBatis中$與#的區(qū)別解析
一、介紹
#(井號(hào)):MyBatis使用#{}作為參數(shù)占位符時(shí),會(huì)創(chuàng)建預(yù)處理語(yǔ)句(Prepared Statement),并將參數(shù)值作為預(yù)處理語(yǔ)句的參數(shù)綁定到SQL語(yǔ)句中。
使用#可以防止SQL注入攻擊,因?yàn)镸yBatis會(huì)自動(dòng)對(duì)參數(shù)值進(jìn)行轉(zhuǎn)義處理。
#{}內(nèi)部可以是參數(shù)的名稱或者參數(shù)的索引位置(例如#{param1}或者#{1})。
SELECT * FROM users WHERE username = #{username}$(美元符號(hào)):MyBatis使用${}作為參數(shù)占位符時(shí),不會(huì)創(chuàng)建預(yù)處理語(yǔ)句。而是直接將參數(shù)值拼接到SQL語(yǔ)句中。
使用$不會(huì)對(duì)參數(shù)值進(jìn)行轉(zhuǎn)義,因此容易受到SQL注入攻擊,除非參數(shù)值是可信的或者已經(jīng)進(jìn)行了適當(dāng)?shù)奶幚怼?/p>
${}內(nèi)部通常是參數(shù)的名稱。
SELECT * FROM ${tableName} WHERE id = #{id}$和#的主要區(qū)別:
a、安全性:#提供預(yù)處理語(yǔ)句的參數(shù)綁定,更安全,可以有效防止SQL注入;$直接將參數(shù)值拼接到SQL語(yǔ)句中,存在SQL注入的風(fēng)險(xiǎn)。
b、性能:#通常性能更好,因?yàn)轭A(yù)處理語(yǔ)句可以重復(fù)使用,而$每次都會(huì)生成新的SQL語(yǔ)句。
c、使用場(chǎng)景:#適用于大多數(shù)情況,特別是當(dāng)參數(shù)是用戶輸入時(shí);$適用于需要?jiǎng)討B(tài)指定表名或列名的情況,因?yàn)檫@些部分不能作為預(yù)處理語(yǔ)句的參數(shù)。
因此,除非有特殊需求,通常推薦使用#來(lái)提高SQL語(yǔ)句的安全性和性能。
二、sql注入風(fēng)險(xiǎn)實(shí)例
1、存在 SQL 注入風(fēng)險(xiǎn)的情況(使用 $):
// Mapper 接口
public interface UserMapper {
User selectUserByUsername(String username);
}
// XML 映射文件(存在注入風(fēng)險(xiǎn))
<select id="selectUserByUsername" resultType="User">
SELECT * FROM users WHERE username = '${username}'
</select>攻擊示例:當(dāng)輸入的 username 為 ' OR '1'='1 時(shí),最終生成的 SQL 語(yǔ)句如下:
SELECT * FROM users WHERE username = '' OR '1'='1'
這個(gè) SQL 語(yǔ)句會(huì)讓所有用戶記錄都被返回。
2、安全處理方式(使用#)
// Mapper 接口
public interface UserMapper {
User selectUserByUsername(String username);
}
// XML 映射文件(安全)
<select id="selectUserByUsername" resultType="User">
SELECT * FROM users WHERE username = #{username}
</select>3、預(yù)編譯過(guò)程
編譯后的 SQL:SELECT * FROM users WHERE username = ?
實(shí)際執(zhí)行時(shí):如果輸入的 username 是 ' OR '1'='1,JDBC 會(huì)對(duì)其進(jìn)行轉(zhuǎn)義,轉(zhuǎn)義后的值為 \' OR \'1\'=\'1。
最終效果:查詢會(huì)去匹配一個(gè)名為 ' OR '1'='1 的用戶,顯然這樣的用戶是不存在的,注入攻擊也就失敗了。
到此這篇關(guān)于mybaits中$與#的區(qū)別解析的文章就介紹到這了,更多相關(guān)mybaits $與#區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot集成Flyway進(jìn)行數(shù)據(jù)庫(kù)版本遷移管理的步驟
這篇文章主要介紹了SpringBoot集成Flyway進(jìn)行數(shù)據(jù)庫(kù)版本遷移管理的步驟,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot框架,感興趣的朋友可以了解下2021-03-03
SpringBoot利用Junit動(dòng)態(tài)代理實(shí)現(xiàn)Mock方法
解決idea的debug模式突然變卡,項(xiàng)目啟動(dòng)變慢的狀況
關(guān)于Java的HashMap多線程并發(fā)問題分析
Spring Boot 訪問安全之認(rèn)證和鑒權(quán)詳解
Java While循環(huán) do-while循環(huán)用法

