最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis中#和$的區(qū)別小結(jié)

 更新時(shí)間:2023年09月20日 09:40:10   作者:不會(huì)敲代碼的程序猿!  
${} 和 #{} 都是 MyBatis 中用來(lái)替換參數(shù)的,它們都可以將用戶傳遞過(guò)來(lái)的參數(shù),替換到 MyBatis 最終生成的 SQL 中,但它們區(qū)別卻是很大的,接下來(lái)我們一起來(lái)看

MyBatis中#和$的區(qū)別

說(shuō)一下為什么要寫這篇文章,最近面試有被問(wèn)到,一下子想不出來(lái)有啥區(qū)別,想記錄一下加深自己的理解,同時(shí)自己也經(jīng)常用MyBatis-Plus忽略了XML文件的編寫和使用,所以需要加深一下這塊的知識(shí)

一、例子

1、#{}將傳入的數(shù)據(jù)當(dāng)作一個(gè)字符串,會(huì)對(duì)傳入的數(shù)據(jù)加上一個(gè)雙引號(hào)。

比如

select * from student where student_name = #{studentName}

如果傳入的值為zhangxiangwei,那么經(jīng)過(guò)Mybatis解析完成之后的語(yǔ)句是

select * from student where student_name="zhangxiangwei"

2.${}將傳入的數(shù)據(jù)直接顯示生成在sql中。

比如

select ${fieldName} from user where user_age = 22

此時(shí),傳入的參數(shù)作為要查詢的字段,如果傳入的值為user_name,則解析成的sql為:

select user_name from user where user_age = 22

二、區(qū)別

1.#{}方式能夠很大程度上防止sql注入,${}無(wú)法防止sql注入。

2.${}方式一般用于傳入數(shù)據(jù)庫(kù)對(duì)象,例如列表和表名,#{}方式一般用來(lái)傳遞接口傳輸過(guò)來(lái)的具體數(shù)據(jù)。

3.由于#{}方式具有更高的安全行,所以能用#{}的地方盡量不要使用${}。

4.Mybatis排序時(shí)使用order by動(dòng)態(tài)參數(shù)時(shí)需要注意,用${}而不是#{}。

5.#符號(hào)(Pound Sign):

  • #符號(hào)用于參數(shù)值的占位,會(huì)將參數(shù)值進(jìn)行預(yù)編譯,并在執(zhí)行SQL語(yǔ)句時(shí)將參數(shù)值安全地傳遞給數(shù)據(jù)庫(kù),防止SQL注入攻擊。

  • 適用于大多數(shù)情況,尤其是當(dāng)參數(shù)值來(lái)自用戶輸入或不可信數(shù)據(jù)時(shí),是更安全的選擇。

  • 參數(shù)值會(huì)被自動(dòng)轉(zhuǎn)義,不需要擔(dān)心特殊字符的處理。

  • 使用#符號(hào)會(huì)產(chǎn)生預(yù)編譯的SQL語(yǔ)句,可以提高數(shù)據(jù)庫(kù)的性能,因?yàn)閿?shù)據(jù)庫(kù)可以緩存相同的預(yù)編譯語(yǔ)句。

<!-- 使用#符號(hào)進(jìn)行參數(shù)占位 -->
<select id="getUserById" parameterType="int" resultType="User">
  SELECT * FROM users
  WHERE id = #{userId}
</select>

6.$符號(hào)(Dollar Sign):

  • $符號(hào)用于簡(jiǎn)單的值替換,不進(jìn)行預(yù)編譯,直接將參數(shù)的值嵌入SQL語(yǔ)句中。

  • 適用于那些不需要參數(shù)值預(yù)編譯,且參數(shù)值是確定且可信的情況,比如用于動(dòng)態(tài)拼接SQL語(yǔ)句的情況。

  • 使用$符號(hào)時(shí),需要小心防止SQL注入攻擊,需要手動(dòng)處理參數(shù)值的安全性。

  • 不會(huì)產(chǎn)生預(yù)編譯的SQL語(yǔ)句,可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)性能較低,因?yàn)槊看蜸QL語(yǔ)句都會(huì)重新解析和執(zhí)行。

<!-- 使用$符號(hào)進(jìn)行簡(jiǎn)單值替換 -->
<select id="getUserByName" parameterType="string" resultType="User">
  SELECT * FROM users
  WHERE username = '${username}'
</select>

三、最后說(shuō)一下 $ 動(dòng)態(tài) 拼接SQL

下面是一個(gè)實(shí)例

<select id="getUsersWithDynamicSorting" parameterType="map" resultType="User">
  SELECT * FROM users
  WHERE 1=1 <!-- 為了方便拼接,可以始終使用一個(gè)始終成立的條件 -->
  <!-- 根據(jù)參數(shù)動(dòng)態(tài)拼接排序字段和排序順序 -->
  <if test="sortField != null and sortOrder != null">
    ORDER BY ${sortField} ${sortOrder}
  </if>
</select>

補(bǔ)充:mybatis中的#{}和${}的區(qū)別

1. 取值范圍不同

MyBatis既可以獲取執(zhí)行SQL時(shí)插入的請(qǐng)求參數(shù),也可以從主配置文件加載的配置文件中獲取配置參數(shù)。 #{} 只能獲取請(qǐng)求參數(shù)的值,無(wú)法獲取配置參數(shù)。 ${} 在MyBatis初始化時(shí)能獲取配置參數(shù),如果沒(méi)有,執(zhí)行時(shí)再獲取請(qǐng)求參數(shù)。

2. 處理方式不同

#{}

如果SQL中只有 #{} 或者可以被配置參數(shù)替換的 ${} ,那么在初始化時(shí) #{} 就被解析成了占位符 ?

如果SQL中有動(dòng)態(tài)標(biāo)簽(例如 if , where ),或者無(wú)法被配置參數(shù)替換的 ${} ,那么 #{} 在執(zhí)行SQL時(shí)才會(huì)被替換成占位符 ? #{} 的值是執(zhí)行SQL時(shí)通過(guò)JDBC的Statement根據(jù)占位符進(jìn)行設(shè)置。

${}

如果可以被配置參數(shù)替換,則在初始化時(shí)已被配置參數(shù)替換,否則在執(zhí)行SQL時(shí)使用請(qǐng)求參數(shù)替換。

${} 的值使用參數(shù)值直接替換,不做任何特殊處理。

3. 安全性不同

#{} 能夠很大程度防止SQL注入。 ${} 無(wú)法防止SQL注入。

所以,能用 #{} 的就別用 ${} 。 ${} 方式一般用于傳入數(shù)據(jù)庫(kù)對(duì)象,例如傳入表名,排序字段等。

4. 測(cè)試驗(yàn)證

以下是自己做過(guò)的一些測(cè)試驗(yàn)證場(chǎng)景:

測(cè)試場(chǎng)景一: ${} 是否能夠獲取配置文件中的參數(shù)?如果能獲取配置參數(shù),那么是初始化時(shí)替換 ${} 還是執(zhí)行時(shí)替換 ${} 。

測(cè)試結(jié)果一: ${} 在MyBatis初始化時(shí),獲取MyBatis主配置文件中加載的配置參數(shù)進(jìn)行替換。

  • SQL中只有 ${} ${} 被替換成配置參數(shù),在所有 ${} 都被替換的情況下,生成的是靜態(tài)SQL對(duì)象。
  • SQL中只有 ${} #{} , ${} 被替換成配置參數(shù),在所有 ${} 都被替換的情況下, #{} 會(huì)被替換成 ? ,且生成靜態(tài)SQL對(duì)象。
  • SQL中存在 ${} 和動(dòng)態(tài)標(biāo)簽, ${} 無(wú)論在動(dòng)態(tài)標(biāo)簽內(nèi)或者外, ${} 都被替換成配置參數(shù),生成動(dòng)態(tài)SQL對(duì)象。
  • SQL中存在 ${} 、 #{} 和動(dòng)態(tài)標(biāo)簽, ${} 被替換成配置參數(shù), #{} 沒(méi)有被替換成 ? ,生成動(dòng)態(tài)SQL對(duì)象。

測(cè)試結(jié)論一:

在MyBatis初始化階段,解析XML配置文件的過(guò)程中,會(huì)對(duì) ${propertyName} 占位符做解析,如果能夠在配置參數(shù)中獲取到 key=propertyName 的值,那么就會(huì)使用配置參數(shù)值替換 ${propertyName} ,否則保留。所以在 xxxMapper.xml 中使用 ${propertyName} 獲取參數(shù)時(shí),需要考慮是獲取配置文件中的值,還是獲取SQL執(zhí)行時(shí)傳入的請(qǐng)求參數(shù)值。這可能會(huì)出現(xiàn)意想不到的結(jié)果。

測(cè)試場(chǎng)景二:

如果SQL中有動(dòng)態(tài)標(biāo)簽或者 ${} 符號(hào),且 ${} 不會(huì)被配置參數(shù)替換時(shí),SQL中的 #{} 在初始化時(shí)替換成 ? ,還是在執(zhí)行時(shí)被替換成 ?

測(cè)試結(jié)果二:

在MyBatis初始化過(guò)程中的測(cè)試結(jié)果:

  • SQL中僅有 #{} , #{} 被替換成 ?
  • SQL中有 #{} ${} , #{} 沒(méi)有被替換成 ? 。SQL中有 #{} 和動(dòng)態(tài)標(biāo)簽, #{} 無(wú)論在動(dòng)態(tài)標(biāo)簽內(nèi)還是外,都沒(méi)有被替換成 ? 。
  • SQL中有 #{} ${} 、動(dòng)態(tài)標(biāo)簽, # {}沒(méi)有被替換成 ? 。

在SQL執(zhí)行過(guò)程中的測(cè)試結(jié)果:

  • SQL中僅有 #{} , #{} 在初始化階段就已被替換成了 ?
  • SQL中有 #{} ${} , #{} 被替換成 ? , ${} 被替換成參數(shù)值。
  • SQL中有 #{} 和動(dòng)態(tài)標(biāo)簽, #{} 被替換成 ? ,動(dòng)態(tài)標(biāo)簽根據(jù)參數(shù)被解析。
  • SQL中有 #{} 、 ${} 和動(dòng)態(tài)標(biāo)簽, #{} 被替換成 ? , ${} 被替換成參數(shù)值,動(dòng)態(tài)標(biāo)簽根據(jù)參數(shù)被解析。

到此這篇關(guān)于MyBatis中#和$的區(qū)別的文章就介紹到這了,更多相關(guān)MyBatis #和$的區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

淮北市| 鸡东县| 阳江市| 宜黄县| 杂多县| 湘西| 全州县| 罗城| 海口市| 宣武区| 威信县| 永安市| 泾阳县| 永康市| 平塘县| 伊吾县| 卫辉市| 巩义市| 清流县| 古丈县| 平潭县| 勃利县| 仁怀市| 甘泉县| 靖边县| 涞源县| 襄城县| 泸定县| 姜堰市| 文成县| 大港区| 津市市| 萍乡市| 左权县| 呼和浩特市| 芦山县| 甘南县| 桃园县| 鹤峰县| 蒙城县| 庆城县|