欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MyBatis 探秘之#{} 與 ${} 參傳差異解碼(數(shù)據(jù)庫(kù)連接池筑牢數(shù)據(jù)交互根基)

 更新時(shí)間:2024年12月30日 11:18:52   作者:GGBondlctrl  
本文詳細(xì)介紹了MyBatis中的`#{}`和`${}`的區(qū)別與使用場(chǎng)景,包括預(yù)編譯SQL和即時(shí)SQL的區(qū)別、安全性問(wèn)題,以及如何正確使用數(shù)據(jù)庫(kù)連接池來(lái)提高性能,感興趣的朋友一起看看吧

???1. #{} 與 ${}的使用

我們?cè)谥暗膶W(xué)習(xí)中,了解到了“#{}”,但是這里的${}是什么呢?其實(shí)這里的${}也具有參數(shù)傳遞的功能但是我們之前為什么不使用$符號(hào)呢?且聽(tīng)下面的分析過(guò)程~~~

1.1integer類型數(shù)據(jù)

我們可以通過(guò)id類整型參數(shù)的傳遞進(jìn)行實(shí)驗(yàn),首先得先創(chuàng)建一個(gè)數(shù)據(jù)庫(kù),如下所示:

接下來(lái)我們知己使用XML的方式進(jìn)行代碼的編寫(xiě):

在Mapper類中:

 List<UserInfo> select2(Integer id);

 這里先定義數(shù)據(jù)的返回類型,然后再在XML文件中實(shí)現(xiàn)查詢SQL的方法:

<select id="select2" resultType="com.example.mybatis.Model.UserInfo">
        select * from user_info where id=#{id}
    </select>

然后再測(cè)試類進(jìn)行測(cè)試后們可以看到如下的打印的日志:

解釋:

可以發(fā)現(xiàn)在SQL查詢語(yǔ)句中,參數(shù)被“?”給替代了,然后下面的參數(shù)就是“2”,此時(shí)可以了解到我們輸?的參數(shù)并沒(méi)有在后?拼接,id的值是使? ? 進(jìn)?占位. 這種SQL 我們稱之為"預(yù)編譯SQL"

然后我們將這里的“#{ }” 替換成“${}”,具體的情況就是如下所示的:

解釋:

可以發(fā)現(xiàn)此時(shí)SQL語(yǔ)句,就沒(méi)有“?”,然后下面的paramters參數(shù)就為空了,然后我們就知道${} 會(huì)直接進(jìn)?字符替換, ?起對(duì)SQL進(jìn)?編譯,不會(huì)像#號(hào)一樣使用占位符;這種我們就稱之為即時(shí)SQL

1.2String類型數(shù)據(jù)

這里我們使用String類來(lái)進(jìn)行匹配查詢,具體的操作還是和上面差不多;

Mapper類的代碼如下:

 List<UserInfo> selectAllByUsername(String username);

然后再XML寫(xiě)SQL語(yǔ)句的操作:

解釋:

此時(shí)可以看到,和上面的string類型的數(shù)據(jù)是一樣的,這里會(huì)標(biāo)明參數(shù)的類型為string類型,然后再進(jìn)行替換占位的時(shí)候會(huì)自動(dòng)添加引號(hào);

然后我們將這里的“#{ }” 替換成“${}”,具體的情況就是如下所示的:

 <select id="selectAllByUsername" resultType="com.example.mybatis.Model.UserInfo">
        select * from user_info where username=${username}
    </select>

這里就是通過(guò)輸入的名字進(jìn)行查詢,將這#號(hào)替換成了$符號(hào),然后再測(cè)試類進(jìn)行測(cè)試后打印的日志報(bào)錯(cuò)了,具體的打印日志如下所示:

解釋:

這里可以看到此時(shí)的$符號(hào)的操作,出現(xiàn)了報(bào)錯(cuò),原因就是BadSql,我們?cè)谏厦婵吹剑捎谥苯哟娴脑?,查詢條件中字符串沒(méi)有出現(xiàn)“ '  '  ”符號(hào),即引號(hào),然后就是SQL語(yǔ)句語(yǔ)法不正確導(dǎo)致錯(cuò)誤;

解決辦法:

在XML編寫(xiě)SQL語(yǔ)句的時(shí)候進(jìn)行手動(dòng)添加' ';

代碼如下:

<select id="selectAllByUsername" resultType="com.example.mybatis.Model.UserInfo">
        select * from user_info where username='${username}'
    </select>

此時(shí)進(jìn)行測(cè)試打印,打印的日志就是如下所示的:

解釋:此時(shí)可以看到在字符串添加了“ ' ' ”雙引號(hào),然后參數(shù)仍然為空;

綜上所述:

#{} 使?的是預(yù)編譯SQL, 通過(guò) ? 占位的?式, 提前對(duì)SQL進(jìn)?編譯, 然后把參數(shù)填充到SQL語(yǔ)句中. #{} 會(huì)根據(jù)參數(shù)類型, ?動(dòng)拼接引號(hào) '' .
${} 使用的就是即時(shí)編譯SQL,會(huì)直接進(jìn)?字符替換, ?起對(duì)SQL進(jìn)?編譯. 如果參數(shù)為字符串, 需要加上引號(hào) ''

???2. #{} 與 ${}的區(qū)別

2.1性能

當(dāng)客?發(fā)送?條SQL語(yǔ)句給服務(wù)器后, ?致流程如下:

1. 解析語(yǔ)法和語(yǔ)義, 校驗(yàn)SQL語(yǔ)句是否正確
2. 優(yōu)化SQL語(yǔ)句, 制定執(zhí)?計(jì)劃
3. 執(zhí)?并返回結(jié)果

?條 SQL如果?上述流程處理, 我們稱之為 Immediate Statements(即時(shí) SQL) 

但是絕?多數(shù)情況下, 某?條 SQL 語(yǔ)句可能會(huì)被反復(fù)調(diào)?執(zhí)?, 或者每次執(zhí)?的時(shí)候只有個(gè)別的值不同(?如 select 的 where ?句值不同, update 的 set ?句值不同, insert 的 values 值不同). 如果每次都需要經(jīng)過(guò)上?的語(yǔ)法解析, SQL優(yōu)化、SQL編譯等,則效率就明顯不?了

總結(jié): 

所以預(yù)編譯SQL就在執(zhí)行上述的優(yōu)化操作后,遇到同樣的SQL語(yǔ)句,就不會(huì)對(duì)SQL進(jìn)行再次的優(yōu)化編譯了,就直接改變參數(shù),省去了解析優(yōu)化等過(guò)程, 以此來(lái)提?效率

預(yù)編譯SQL的性能比即時(shí)SQL的性能更高;

2.2安全性 

這里出現(xiàn)的安全性就是(SQL注入)

SQL注?:是通過(guò)操作輸?的數(shù)據(jù)來(lái)修改事先定義好的SQL語(yǔ)句,以達(dá)到執(zhí)?代碼對(duì)服務(wù)器進(jìn)?攻擊的?法。由于沒(méi)有對(duì)??輸?進(jìn)?充分檢查,?SQL?是拼接?成,在??輸?參數(shù)時(shí),在參數(shù)中添加?些SQL關(guān)鍵字,達(dá)到改變SQL運(yùn)?結(jié)果的?的,也可以完成惡意攻擊

注意:這里只針對(duì)的就是${ }符號(hào);

假如我們?cè)诖朔?hào)中添加    ' or 1='1

然后在#{ }運(yùn)行中,可以發(fā)現(xiàn)此時(shí)的此時(shí)的打印日志告訴我們,這里的字符串在數(shù)據(jù)庫(kù)中沒(méi)有找到

如下所示:

這里的結(jié)果確實(shí)如我們所料,但是在${ }符號(hào)中,如下所示:

解釋:

哎奇怪,怎么會(huì)出現(xiàn)這種情況,這個(gè)字符串在我們的數(shù)據(jù)庫(kù)列中就沒(méi)有這個(gè)字段;但是為啥就全部搜索出來(lái)了呢??

因?yàn)槠唇拥膯?wèn)題和原因,所以這里出現(xiàn)了誤判,'  {'    or     1='1}  ' 拼接后成了以下SQL語(yǔ)句

'  '    or     1='1'

解釋:

具體的意思就是為空或者為true,這就是為啥全部搜索出來(lái)了,這里存在SQL關(guān)鍵字or;

所以SQL注?是?種?常常?的數(shù)據(jù)庫(kù)攻擊?段, SQL注?漏洞也是?絡(luò)世界中最普遍的漏洞之?.
如果發(fā)?在??登錄的場(chǎng)景中, 密碼輸?為 ' or 1='1 , 就可能完成登錄;

總之在后面的學(xué)習(xí)中能用#{} 那么就使用#{ },${ }非特殊情況盡量不要使用 

???3.${ }使用場(chǎng)景

3.1排序

在實(shí)現(xiàn)排序功能的時(shí)候,由于“desc”不需要使用引號(hào),所以這里我們就可以使用${}符號(hào)

具體的代碼如下所示:

<select id="selectAllById" resultType="com.example.mybatis.Model.UserInfo">
        select * from user_info order by id ${sort}
    </select>

這里即時(shí)XML的寫(xiě)法,可以看到此時(shí)order by id然后排序關(guān)鍵詞,就不需要引號(hào),那么此時(shí)我們就可以使用$符號(hào);

在測(cè)試類中的實(shí)現(xiàn)代碼:

 @Test
    void selectAllById() {
        userInfoXMLMapper.selectAllById("desc");
    }

我們這里就是按照降序排序進(jìn)行查詢結(jié)果的排序的,最后打印的日志如下所示:

解釋:

上面的兩行就是SQL語(yǔ)句和參數(shù),參數(shù)為空,然后即時(shí)SQL進(jìn)行拼接,SQL語(yǔ)句就成為了一個(gè)查詢語(yǔ)句按照降排序的方式進(jìn)行查詢結(jié)果的展示;

3.2模糊查詢

代碼如下所示:

 <select id="selectByUsername" resultType="com.example.mybatis.Model.UserInfo">
        select * from user_info where username like '%${username}%'
    </select>

這里也是不需要引號(hào),然后也可以使用$符號(hào),在測(cè)試類中代碼:

@Test
    void selectByUsername() {
        userInfoXMLMapper.selectByUsername("o");
    }

最后打印的日志如下所示:

解釋:

這里的模糊查詢,中間的參數(shù)是不需要自動(dòng)添加引號(hào)的,并且這里的模糊查詢的條件就是查找名字里包含“o”的那一段數(shù)據(jù);

但是這里由于注入等安全性,這里我們可以使用#進(jìn)行另一種寫(xiě)法,具體的代碼如下所示:

 <select id="selectByUsername2" resultType="com.example.mybatis.Model.UserInfo">
        select * from user_info where username like concat('%',#{username},'%')
    </select>

解釋:

這里使用concat關(guān)鍵字,實(shí)現(xiàn)需要引號(hào)的拼接操作,這樣就可以使用#{}來(lái)進(jìn)行參數(shù)的傳遞,幾避免了SQL注入的安全問(wèn)題,還可能提高了執(zhí)行的效率;

???4.數(shù)據(jù)庫(kù)連接池

4.1介紹

數(shù)據(jù)庫(kù)連接池負(fù)責(zé)分配、管理和釋放數(shù)據(jù)庫(kù)連接,它允許應(yīng)?程序重復(fù)使??個(gè)現(xiàn)有的數(shù)據(jù)庫(kù)連接,?不是再重新建??個(gè)

沒(méi)有使?數(shù)據(jù)庫(kù)連接池的情況: 每次執(zhí)?SQL語(yǔ)句, 要先創(chuàng)建?個(gè)新的連接對(duì)象, 然后執(zhí)?SQL語(yǔ)句, SQL語(yǔ)句執(zhí)?完, 再關(guān)閉連接對(duì)象釋放資源. 這種重復(fù)的創(chuàng)建連接, 銷毀連接?較消耗資源

使?數(shù)據(jù)庫(kù)連接池的情況: 程序啟動(dòng)時(shí), 會(huì)在數(shù)據(jù)庫(kù)連接池中創(chuàng)建?定數(shù)量的Connection對(duì)象, 當(dāng)客?請(qǐng)求數(shù)據(jù)庫(kù)連接池, 會(huì)從數(shù)據(jù)庫(kù)連接池中獲取Connection對(duì)象, 然后執(zhí)?SQL, SQL語(yǔ)句執(zhí)?完, 再把Connection歸還給連接池 

優(yōu)點(diǎn):

1. 減少了?絡(luò)開(kāi)銷
2. 資源重?
3. 提升了系統(tǒng)的性能 

4.2使用

常?的數(shù)據(jù)庫(kù)連接池:

• C3P0
• DBCP
• Druid
• Hikari

主流就是Hikari,Druid;

我們的SpringBoot默認(rèn)使用的就是Hikari;日志如下所示:

可以看到這就是springboot默認(rèn)使用的就是Hikari;

???5.總結(jié)

本期小編主要講解了關(guān)于#{ },${ },的區(qū)別與如何進(jìn)行使用,講解了兩者的性能比較,比較重要的SQL注入的問(wèn)題,以及簡(jiǎn)單的闡述了數(shù)據(jù)庫(kù)連接池的介紹~~~

到此這篇關(guān)于MyBatis 探秘:#{} 與 ${} 參傳差異解碼,數(shù)據(jù)庫(kù)連接池筑牢數(shù)據(jù)交互根基的文章就介紹到這了,更多相關(guān)MyBatis #{} 與 ${} 參傳差異解碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java同步非阻塞模式NIO處理IO數(shù)據(jù)

    Java同步非阻塞模式NIO處理IO數(shù)據(jù)

    這篇文章主要介紹了Java同步非阻塞模式NIO處理IO數(shù)據(jù),服務(wù)器實(shí)現(xiàn)模式為一個(gè)請(qǐng)求一個(gè)線程,即客戶端發(fā)送的鏈接請(qǐng)求都會(huì)注冊(cè)到選擇器上,選擇器輪詢到連接有IO請(qǐng)求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理,需要的朋友可以參考下
    2023-10-10
  • 基于Java?NIO編寫(xiě)一個(gè)簡(jiǎn)單版Netty服務(wù)端

    基于Java?NIO編寫(xiě)一個(gè)簡(jiǎn)單版Netty服務(wù)端

    基于?NIO?實(shí)現(xiàn)的網(wǎng)絡(luò)框架,可以用少量的線程,處理大量的連接,更適用于高并發(fā)場(chǎng)景,所以被就將利用NIO編寫(xiě)一個(gè)簡(jiǎn)單版Netty服務(wù)端,需要的可以參考下
    2024-04-04
  • Java爬蟲(chóng) 信息抓取的實(shí)現(xiàn)

    Java爬蟲(chóng) 信息抓取的實(shí)現(xiàn)

    本文主要介紹 Java爬蟲(chóng) 信息抓取的實(shí)現(xiàn),這里詳細(xì)介紹了如何實(shí)現(xiàn)該方法,并附示例代碼供大家學(xué)習(xí)參考,有興趣的小伙伴可以參考下
    2016-09-09
  • MyBatis-Plus集成Druid環(huán)境搭建的詳細(xì)教程

    MyBatis-Plus集成Druid環(huán)境搭建的詳細(xì)教程

    這篇文章主要介紹了MyBatis-Plus集成Druid環(huán)境搭建的詳細(xì)教程,需要的朋友可以參考下
    2020-08-08
  • myeclipse10配置tomcat教程詳解

    myeclipse10配置tomcat教程詳解

    這篇文章主要為大家詳細(xì)介紹了myeclipse10配置tomcat的教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Java類中this關(guān)鍵字與static關(guān)鍵字的用法解析

    Java類中this關(guān)鍵字與static關(guān)鍵字的用法解析

    這篇文章主要介紹了Java類中this關(guān)鍵字與static關(guān)鍵字的用法解析,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • MybatisPlus查詢數(shù)據(jù)日期格式化問(wèn)題解決方法

    MybatisPlus查詢數(shù)據(jù)日期格式化問(wèn)題解決方法

    MyBatisPlus是MyBatis的增強(qiáng)工具,支持常規(guī)的CRUD操作以及復(fù)雜的聯(lián)表查詢等功能,這篇文章主要給大家介紹了關(guān)于MybatisPlus查詢數(shù)據(jù)日期格式化問(wèn)題的解決方法,需要的朋友可以參考下
    2023-10-10
  • Java如何比較兩個(gè)對(duì)象并獲取不相等的字段詳解

    Java如何比較兩個(gè)對(duì)象并獲取不相等的字段詳解

    這篇文章主要給大家介紹了關(guān)于Java如何比較兩個(gè)對(duì)象并獲取不相等的字段以及JAVA判斷(獲?。﹥蓚€(gè)相同對(duì)象不同的數(shù)據(jù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-11-11
  • Spring測(cè)試 其實(shí)很簡(jiǎn)單

    Spring測(cè)試 其實(shí)很簡(jiǎn)單

    這篇文章主要為大家詳細(xì)介紹了Spring測(cè)試,其實(shí)很簡(jiǎn)單,揭開(kāi)集成測(cè)試神秘的面紗,感興趣的小伙伴們可以參考一下
    2016-07-07
  • spring中的注入list集合

    spring中的注入list集合

    這篇文章主要介紹了spring中的注入list集合問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11

最新評(píng)論