亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

我們在之前的學(xué)習(xí)中,了解到了“#{}”,但是這里的${}是什么呢?其實(shí)這里的${}也具有參數(shù)傳遞的功能但是我們之前為什么不使用$符號呢?且聽下面的分析過程~~~

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

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

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

在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>

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

解釋:

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

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

解釋:

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

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

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

Mapper類的代碼如下:

 List<UserInfo> selectAllByUsername(String username);

然后再XML寫SQL語句的操作:

解釋:

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

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

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

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

解釋:

這里可以看到此時的$符號的操作,出現(xiàn)了報錯,原因就是BadSql,我們在上面看到,由于直接代替的原因,查詢條件中字符串沒有出現(xiàn)“ '  '  ”符號,即引號,然后就是SQL語句語法不正確導(dǎo)致錯誤;

解決辦法:

在XML編寫SQL語句的時候進(jìn)行手動添加' ';

代碼如下:

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

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

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

綜上所述:

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

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

2.1性能

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

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

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

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

總結(jié): 

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

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

2.2安全性 

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

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

注意:這里只針對的就是${ }符號;

假如我們在此符號中添加    ' or 1='1

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

如下所示:

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

解釋:

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

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

'  '    or     1='1'

解釋:

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

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

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

???3.${ }使用場景

3.1排序

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

具體的代碼如下所示:

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

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

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

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

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

解釋:

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

3.2模糊查詢

代碼如下所示:

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

這里也是不需要引號,然后也可以使用$符號,在測試類中代碼:

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

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

解釋:

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

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

 <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)需要引號的拼接操作,這樣就可以使用#{}來進(jìn)行參數(shù)的傳遞,幾避免了SQL注入的安全問題,還可能提高了執(zhí)行的效率;

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

4.1介紹

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

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

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

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

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

4.2使用

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

• C3P0
• DBCP
• Druid
• Hikari

主流就是Hikari,Druid;

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

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

???5.總結(jié)

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

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

相關(guān)文章

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

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

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

    基于Java?NIO編寫一個簡單版Netty服務(wù)端

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

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

    本文主要介紹 Java爬蟲 信息抓取的實(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的教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Java類中this關(guān)鍵字與static關(guān)鍵字的用法解析

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

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

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

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

    Java如何比較兩個對象并獲取不相等的字段詳解

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

    Spring測試 其實(shí)很簡單

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

    spring中的注入list集合

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

最新評論