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

mybatis中的字符串拼接問(wèn)題

 更新時(shí)間:2023年02月07日 09:11:33   作者:藤原·拓海  
這篇文章主要介紹了mybatis中的字符串拼接問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

mybatis字符串拼接

MyBatis中拼接字符串有兩種方式。

使用CONCAT 函數(shù)

SELECT * FROM user WHERE name LIKE CONCAT(CONCAT(‘%', #{name}), ‘%')

使用${ } 代替 #{ }

因?yàn)?{ }直接傳入SQL,而#{ }傳入的是字符串帶有引號(hào)

SELECT * FROM user WHERE name LIKE ‘%${name}%'

原因:

#{}能夠有效防止SQL注入,但是也有它的缺點(diǎn),它會(huì)把傳入的數(shù)據(jù)自動(dòng)加上一個(gè)雙引號(hào),所以如果要的是數(shù)字的話,就會(huì)比較尷尬。

而${}可以直接解析出原本的數(shù)據(jù),所以需要數(shù)值比較的話,還是要加${}。

mybatis 拼接動(dòng)態(tài)表名、字段名

在項(xiàng)目中遇到個(gè)需求是要?jiǎng)討B(tài)的根據(jù)前臺(tái)傳入的字段名稱和升降序條件在mybatis里動(dòng)態(tài)拼接sql語(yǔ)句進(jìn)行查詢。現(xiàn)在對(duì)解決方法進(jìn)行下總結(jié),希望對(duì)遇到同樣問(wèn)題的伙伴有些幫助。

動(dòng)態(tài)SQL是mybatis的強(qiáng)大特性之一,mybatis在對(duì)sql語(yǔ)句進(jìn)行預(yù)編譯之前,會(huì)對(duì)sql進(jìn)行動(dòng)態(tài)解析,解析為一個(gè)BoundSql對(duì)象,也是在此處對(duì)動(dòng)態(tài)sql進(jìn)行處理。

這里我們?cè)敿?xì)說(shuō)下動(dòng)態(tài)表名和字段名。下面讓我們先來(lái)熟悉下mybatis里#{}與${}的用法:

在動(dòng)態(tài)sql解析過(guò)程,#{}與${}的效果是不一樣的:

#{ } 解析為一個(gè) JDBC 預(yù)編譯語(yǔ)句(prepared statement)的參數(shù)標(biāo)記符。

如以下sql語(yǔ)句

select * from user where name = #{name};

會(huì)被解析為:

select * from user where name = ?;

可以看到#{}被解析為一個(gè)參數(shù)占位符?。

${ } 僅僅為一個(gè)純碎的 string 替換,在動(dòng)態(tài) SQL 解析階段將會(huì)進(jìn)行變量替換

如以下sql語(yǔ)句:

select * from user where name = ${name};

當(dāng)我們傳遞參數(shù)“sprite”時(shí),sql會(huì)解析為:

select * from user where name = "sprite";

可以看到預(yù)編譯之前的sql語(yǔ)句已經(jīng)不包含變量name了。

綜上所得, ${ } 的變量的替換階段是在動(dòng)態(tài) SQL 解析階段,而 #{ }的變量的替換是在 DBMS 中。

#{}與${}的區(qū)別可以簡(jiǎn)單總結(jié)如下:

  • #{}將傳入的參數(shù)當(dāng)成一個(gè)字符串,會(huì)給傳入的參數(shù)加一個(gè)雙引號(hào)
  • ${}將傳入的參數(shù)直接顯示生成在sql中,不會(huì)添加引號(hào)
  • #{}能夠很大程度上防止sql注入,${}無(wú)法防止sql注入

${}在預(yù)編譯之前已經(jīng)被變量替換了,這會(huì)存在sql注入的風(fēng)險(xiǎn)。如下sql

select * from ${tableName} where name = ${name}

如果傳入的參數(shù)tableName為user; delete user; --,那么sql動(dòng)態(tài)解析之后,預(yù)編譯之前的sql將變?yōu)椋?/p>

select * from user; delete user; -- where name = ?;
--之后的語(yǔ)句將作為注釋不起作用,頓時(shí)我和我的小伙伴驚呆了?。?!看到?jīng)],本來(lái)的查詢語(yǔ)句,竟然偷偷的包含了一個(gè)刪除表數(shù)據(jù)的sql,是刪除,刪除,刪除?。?!重要的事情說(shuō)三遍,可想而知,這個(gè)風(fēng)險(xiǎn)是有多大。
  • ${}一般用于傳輸數(shù)據(jù)庫(kù)的表名、字段名等
  • 能用#{}的地方盡量別用${}

進(jìn)入正題,通過(guò)上面的分析,相信大家可能已經(jīng)對(duì)如何動(dòng)態(tài)調(diào)用表名和字段名有些思路了。示例如下:

? <select id="getUser" resultType="java.util.Map" parameterType="java.lang.String" statementType="STATEMENT">
? ? select?
? ? ? ? ${columns}
? ? from ${tableName}
? ? ? ? where COMPANY_REMARK = ${company}
? </select>

要實(shí)現(xiàn)動(dòng)態(tài)調(diào)用表名和字段名,就不能使用預(yù)編譯了,需添加statementType="STATEMENT"" 。

statementType:STATEMENT(非預(yù)編譯),PREPARED(預(yù)編譯)或CALLABLE中的任意一個(gè),這就告訴 MyBatis 分別使用Statement,PreparedStatement或者CallableStatement。默認(rèn):PREPARED。這里顯然不能使用預(yù)編譯,要改成非預(yù)編譯。

其次,sql里的變量取值是${xxx},不是#{xxx}。

因?yàn)?{}是將傳入的參數(shù)直接顯示生成sql,如${xxx}傳入的參數(shù)為字符串?dāng)?shù)據(jù),需在參數(shù)傳入前加上引號(hào),如:

String name = "sprite";
name = "'" + name + "'";

這樣,sql就變成:

select * from user where name = 'sprite';

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java代碼實(shí)現(xiàn)微信頁(yè)面滾動(dòng)防露底(核心代碼)

    Java代碼實(shí)現(xiàn)微信頁(yè)面滾動(dòng)防露底(核心代碼)

    這篇文章主要介紹了Java代碼實(shí)現(xiàn)微信頁(yè)面滾動(dòng)防露底的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • Maven聚合開(kāi)發(fā)實(shí)例詳解

    Maven聚合開(kāi)發(fā)實(shí)例詳解

    這篇文章主要介紹了Maven聚合開(kāi)發(fā)實(shí)例代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • Java線上CPU內(nèi)存沖高問(wèn)題排查解決步驟

    Java線上CPU內(nèi)存沖高問(wèn)題排查解決步驟

    這篇文章主要介紹了Java線上CPU內(nèi)存沖高問(wèn)題排查解決步驟的相關(guān)資料,Java程序在實(shí)際生產(chǎn)過(guò)程中經(jīng)常遇到CPU或內(nèi)存使用率高的問(wèn)題,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • 如何獲取java新IO的Path文件大小

    如何獲取java新IO的Path文件大小

    這篇文章主要介紹了如何獲取java新IO的Path文件大小,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • maven打包成第三方j(luò)ar包且把pom依賴包打入進(jìn)來(lái)的方法

    maven打包成第三方j(luò)ar包且把pom依賴包打入進(jìn)來(lái)的方法

    這篇文章主要介紹了maven打包成第三方j(luò)ar包且把pom依賴包打入進(jìn)來(lái)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Springboot快速集成sse服務(wù)端推流(最新整理)

    Springboot快速集成sse服務(wù)端推流(最新整理)

    SSE?Server-Sent?Events是一種允許服務(wù)器向客戶端推送實(shí)時(shí)數(shù)據(jù)的技術(shù),它建立在?HTTP?和簡(jiǎn)單文本格式之上,提供了一種輕量級(jí)的服務(wù)器推送方式,通常也被稱為“事件流”(Event?Stream),這篇文章主要介紹了Springboot快速集成sse服務(wù)端推流(最新整理),需要的朋友可以參考下
    2024-02-02
  • intellij idea tomcat熱部署配置教程

    intellij idea tomcat熱部署配置教程

    這篇文章主要介紹了intellij idea tomcat熱部署配置教程圖解,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-07-07
  • Spring學(xué)習(xí)之動(dòng)態(tài)代理(JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理)

    Spring學(xué)習(xí)之動(dòng)態(tài)代理(JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理)

    本篇文章主要介紹了Spring學(xué)習(xí)之動(dòng)態(tài)代理(JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 解決IDEA創(chuàng)建第一個(gè)spring boot項(xiàng)目提示cannot resolve xxx等錯(cuò)誤

    解決IDEA創(chuàng)建第一個(gè)spring boot項(xiàng)目提示cannot resolve xxx等

    這篇文章主要介紹了解決IDEA創(chuàng)建第一個(gè)spring boot項(xiàng)目提示cannot resolve xxx等錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 全網(wǎng)最全Mybatis-Plus詳解

    全網(wǎng)最全Mybatis-Plus詳解

    Mybatis-Plus是一個(gè)Mybatis(opens?new?window)的增強(qiáng)工具,在Mybatis的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開(kāi)發(fā),這篇文章主要介紹了全網(wǎng)最全Mybatis-Plus詳解,需要的朋友可以參考下
    2024-05-05

最新評(píng)論

吐鲁番市| 陈巴尔虎旗| 遂平县| 屯留县| 平原县| 高州市| 峨眉山市| 阿巴嘎旗| 池州市| 句容市| 淅川县| 德清县| 乌海市| 拉萨市| 綦江县| 上杭县| 郎溪县| 阿拉尔市| 苍梧县| 清新县| 榕江县| 德安县| 黄浦区| 布尔津县| 昔阳县| 清新县| 阿拉善左旗| 天祝| 三台县| 曲阜市| 山东| 婺源县| 廊坊市| 新乡县| 黔南| 宣城市| 德保县| 佛坪县| 南汇区| 商水县| 滁州市|