#{} 和 ${} 的區(qū)別 — 詳細(xì)!

#{}和${}這兩個(gè)語法是為了動(dòng)態(tài)傳遞參數(shù)而存在的竞惋,是Mybatis實(shí)現(xiàn)動(dòng)態(tài)SQL的基礎(chǔ)柜去,總體上他們的作用是一致的(為了動(dòng)態(tài)傳參),但是在編譯過程拆宛、是否自動(dòng)加單引號嗓奢、安全性、使用場景等方面有很多不同浑厚,下面詳細(xì)比較兩者間的區(qū)別蔓罚。

預(yù)編譯可以類比java類的編譯椿肩,java類被編譯成class文件,載入虛擬機(jī)豺谈,載入虛擬機(jī)的字節(jié)碼文件可以先被編譯成機(jī)器碼郑象,那么在執(zhí)行某行代碼的時(shí)候就可以直接執(zhí)行編譯后的機(jī)器碼,而不用從字節(jié)碼開始編譯再執(zhí)行茬末,那么執(zhí)行效率就高了厂榛。這也是為啥熱機(jī)狀態(tài)比冷機(jī)狀態(tài)可以抗更多負(fù)載的原因。

Sql的預(yù)編譯也是一樣的道理丽惭,在執(zhí)行前就編譯好击奶,等執(zhí)行時(shí)直接取編譯結(jié)果去執(zhí)行。省去編譯時(shí)間责掏。Sql預(yù)編譯后會在參數(shù)位置用占位符表示柜砾。所以預(yù)編譯就是:數(shù)據(jù)庫驅(qū)動(dòng)在發(fā)送Sql和參數(shù)到DBMS之前,先對Sql語句進(jìn)行編譯處理换衬,之后DBMS則可以直接對Sql進(jìn)行處理痰驱,不需要再次編譯,提高了性能瞳浦。這一點(diǎn)mybatis 默認(rèn)情況下担映,將對所有的Sql 進(jìn)行預(yù)編譯處理。

預(yù)編譯可以將多個(gè)操作步驟合并成一個(gè)步驟叫潦,一般而言蝇完,越復(fù)雜的sql,編譯程度也會復(fù)雜矗蕊,難度大短蜕,耗時(shí),費(fèi)性能傻咖,而預(yù)編譯可以合并這些操作忿危,預(yù)編譯之后DBMS可以省去編譯直接運(yùn)行sql。

預(yù)編譯語句可以重復(fù)利用没龙。把一個(gè) sql 預(yù)編譯后產(chǎn)生的 PreparedStatement 對象緩存下來,下次對于同一個(gè)sql缎玫,可以直接使用這個(gè)緩存的 PreparedState 對象硬纤。

上面列舉了#{}?${}?的區(qū)別,接下來結(jié)合代碼及SQL語句打印日志進(jìn)行說明:

關(guān)于SQL語句打印赃磨,若是Spring Boot集成的Mybatis項(xiàng)目可以在application.yml文件中加入以下配置:

#{}動(dòng)態(tài)獲取id時(shí)筝家,sql語句的打印顯示的是一個(gè)?“1”?,沒有占位符邻辉,直接顯示溪王。

主要指的就是防SQL注入腮鞍,什么是SQL注入?以上面的角色查詢?yōu)槔喝绻藭r(shí)的傳參 name = "富貴 or name = 狗蛋"?

可以看到SQL語句的查詢規(guī)則已經(jīng)改變莹菱,原本是查一個(gè)叫名字叫“富貴 or name=狗蛋”的角色 移国,現(xiàn)在變成了查一個(gè)名字叫“富貴”或者叫“狗蛋”的角色,這種通過傳參就能改變SQL語句原本規(guī)則的操作就是SQL注入道伟,這個(gè)在實(shí)際生產(chǎn)中當(dāng)然是危險(xiǎn)的迹缀,攻擊者可以把SQL命令插入到Web表單的輸入域或頁面請求的查詢字符串中,欺騙服務(wù)器執(zhí)行惡意的SQL命令蜜徽。

可以看到祝懂,${} 直接拼接的方式可能引起SQL注入,不安全拘鞋。那 #{} 為啥就可以防止SQL注入呢砚蓬?

這里用Mybatis默認(rèn)的?0?和 1 來代替?zhèn)鲄ⅲ鶕?jù)版本不同盆色,也可能是用arg0灰蛙、arg1、arg2傅事,或者 param1 缕允、param2 ,可以根據(jù)報(bào)錯(cuò)信息進(jìn)行修改蹭越,如下:

${}?時(shí)障本,用 0 和 1雖然不會報(bào)錯(cuò),但是會直接當(dāng)成參數(shù)執(zhí)行响鹃。一般默認(rèn)參數(shù)是param1驾霜、param2...

1、能用?#{}?的地方就用?#{}买置,盡量少用?${}

2粪糙、表名作參數(shù),或者order by 排序時(shí)用?${}

3忿项、傳參時(shí)參數(shù)使用@Param("")注解

tips:

@Param注解的作用是給參數(shù)命名蓉冈,參數(shù)命名后就能根據(jù)名字得到參數(shù)值(相當(dāng)于又加了一層密)如:

Role selectById(@Param("roleId")?String id);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市轩触,隨后出現(xiàn)的幾起案子寞酿,更是在濱河造成了極大的恐慌,老刑警劉巖脱柱,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伐弹,死亡現(xiàn)場離奇詭異,居然都是意外死亡榨为,警方通過查閱死者的電腦和手機(jī)惨好,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門煌茴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人日川,你說我怎么就攤上這事蔓腐。” “怎么了逗鸣?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵合住,是天一觀的道長。 經(jīng)常有香客問我撒璧,道長透葛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任卿樱,我火速辦了婚禮僚害,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘繁调。我一直安慰自己萨蚕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布蹄胰。 她就那樣靜靜地躺著岳遥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪裕寨。 梳的紋絲不亂的頭發(fā)上浩蓉,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機(jī)與錄音宾袜,去河邊找鬼捻艳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛庆猫,可吹牛的內(nèi)容都是我干的认轨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼月培,長吁一口氣:“原來是場噩夢啊……” “哼嘁字!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起杉畜,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤纪蜒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后寻行,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匾荆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年拌蜘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了杆烁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡简卧,死狀恐怖兔魂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情举娩,我是刑警寧澤析校,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站铜涉,受9級特大地震影響智玻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芙代,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一吊奢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纹烹,春花似錦页滚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至片挂,卻和暖如春幻林,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宴卖。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工滋将, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人症昏。 一個(gè)月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓随闽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親肝谭。 傳聞我的和親對象是個(gè)殘疾皇子掘宪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容