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

MyBatis中不建議使用where?1=1原因詳解

 更新時(shí)間:2022年06月21日 17:11:32   作者:Java中文社群  
這篇文章主要為大家介紹了MyBatis中不建議使用where?1=1的原因詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

最近接手了一個(gè)老項(xiàng)目,“愉悅的心情”自然無(wú)以言表,做開(kāi)發(fā)的朋友都懂,這里就不多說(shuō)了,都是淚...

接手老項(xiàng)目,自然是要先熟悉一下業(yè)務(wù)代碼,然而在翻閱 mapper 文件時(shí),發(fā)現(xiàn)了一個(gè)比較詭異的事情。這里給出簡(jiǎn)化后的業(yè)務(wù)代碼:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="list" resultType="com.example.demo.model.User">
        select * from user
        where 1=1
        <if test="name!=null">
            and name=#{name}
        </if>
        <if test="password!=null">
            and password=#{password}
        </if>
    </select>
</mapper>

機(jī)智的小伙伴可能已經(jīng)看出了問(wèn)題,在眾多 mapper 中發(fā)現(xiàn)了一個(gè)相同的想象,幾乎所有的 mapper 中都包含了一個(gè)無(wú)用的拼接 SQL:where 1=1。作為一個(gè)幾乎有代碼潔癖癥的人,自然是忍不住動(dòng)手改造一番了。

錯(cuò)誤的改造方式

既然是去掉 where 1=1,那最簡(jiǎn)單的方式就是將它直接從代碼中刪除了,如下代碼所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="list" resultType="com.example.demo.model.User">
        select * from user
            where
            <if test="name!=null">
                name=#{name}
            </if>
            <if test="password!=null">
                and password=#{password}
            </if>
    </select>
</mapper>

以上代碼刪除了 1=1,并且把第一個(gè) name 查詢(xún)中的 and 去掉了,以防 SQL 查詢(xún)報(bào)錯(cuò)。

但這樣就沒(méi)問(wèn)題了嗎?我們直接來(lái)看結(jié)果,當(dāng)包含參數(shù) name 查詢(xún)時(shí),結(jié)果如下:

一切順利成章,完美的一塌糊涂。

然而,當(dāng)省略 name 參數(shù)時(shí)(因?yàn)?name 為非必要參數(shù),所以可以省略),竟然引發(fā)了以下異常:

又或者只有 password 查詢(xún)時(shí),結(jié)果也是一樣:

都是報(bào)錯(cuò)信息,那腫么辦呢?難不成把 1=1 恢復(fù)回去?

正確的改進(jìn)方式

其實(shí)不用,在 MyBatis 中早已經(jīng)想到了這個(gè)問(wèn)題,我們可以將 SQL 中的 where 關(guān)鍵字換成 MyBatis 中的 標(biāo)簽,并且給每個(gè) 標(biāo)簽內(nèi)都加上 and 拼接符,這樣問(wèn)題就解決了,如下代碼所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
    <select id="list" resultType="com.example.demo.model.User">
        select * from user
        <where>
            <if test="name!=null">
               and name=#{name}
            </if>
            <if test="password!=null">
                and password=#{password}
            </if>
        </where>
    </select>
</mapper>

代碼改造完成之后,接下來(lái)我們來(lái)測(cè)試一下所有的請(qǐng)求場(chǎng)景。

不傳任何參數(shù)的請(qǐng)求

此時(shí)我們可以不傳遞任何參數(shù)(查詢(xún)所有數(shù)據(jù)),如下圖所示:

生成的 SQL 語(yǔ)句如下:

傳遞 1 個(gè)參數(shù)的請(qǐng)求

也可以傳遞 1 個(gè)參數(shù),根據(jù) name 進(jìn)行查詢(xún),如下圖所示:

生成的 SQL 如下圖所示:

也可以只根據(jù) password 進(jìn)行查詢(xún),如下圖所示:

生成的 SQL 如下圖所示:

傳遞 2 個(gè)參數(shù)的請(qǐng)求

也可以根據(jù) name 加 password 的方式進(jìn)行聯(lián)合查詢(xún),如下圖所示:

生成的 SQL 如下圖所示:

用法解析

我們驚喜的發(fā)現(xiàn),在使用了 標(biāo)簽之后,無(wú)論是任何查詢(xún)場(chǎng)景,傳一個(gè)或者傳多個(gè)參數(shù),或者直接不傳遞任何參數(shù),都可以輕松搞定。

首先, 標(biāo)簽會(huì)判斷,如果沒(méi)有任何參數(shù),則不會(huì)在 SQL 語(yǔ)句中拼接 where 查詢(xún),反之才會(huì)拼接 where 查詢(xún);其次在 查詢(xún)的 標(biāo)簽中,每個(gè) 標(biāo)簽都可以加 and 關(guān)鍵字,MyBatis 會(huì)自動(dòng)將第一個(gè)條件前面的 and 關(guān)鍵字刪除掉,從而不會(huì)導(dǎo)致 SQL 語(yǔ)法錯(cuò)誤,這一點(diǎn)官方文檔中也有說(shuō)明,如下圖所示:

總結(jié)

在 MyBatis 中,建議盡量避免使用無(wú)意義的 SQL 拼接 where 1=1,我們可以使用 標(biāo)簽來(lái)替代 where 1=1,這樣的寫(xiě)既簡(jiǎn)潔又優(yōu)雅,何樂(lè)而不為呢?以上內(nèi)容僅為個(gè)人觀點(diǎn),更多關(guān)于MyBatis不建議用where 1=1的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java并發(fā)編程之線(xiàn)程之間的共享和協(xié)作

    Java并發(fā)編程之線(xiàn)程之間的共享和協(xié)作

    這篇文章主要介紹了Java并發(fā)編程之線(xiàn)程之間的共享和協(xié)作,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有一定的幫助,需要的朋友可以參考下
    2021-04-04
  • Java項(xiàng)目中添加外部jar包的兩種方式(收藏版)

    Java項(xiàng)目中添加外部jar包的兩種方式(收藏版)

    這篇文章主要介紹了java項(xiàng)目中添加外部jar包的兩種方式,第二種方式是將外部jar包引入到本地maven倉(cāng)庫(kù)中,本文給大家講解的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • Java虛擬機(jī)運(yùn)行時(shí)棧的棧幀

    Java虛擬機(jī)運(yùn)行時(shí)棧的棧幀

    本節(jié)將會(huì)介紹一下Java虛擬機(jī)棧中的棧幀,會(huì)對(duì)棧幀的組成部分(局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口)分別進(jìn)行介紹,最后還會(huì)通過(guò)javap命令反解析編譯后的.class文件,進(jìn)行分析方法執(zhí)行時(shí)的局部變量表、操作數(shù)棧等
    2021-09-09
  • Java如何實(shí)現(xiàn)圖片的疊加與拼接操作

    Java如何實(shí)現(xiàn)圖片的疊加與拼接操作

    這篇文章主要介紹了Java如何實(shí)現(xiàn)圖片的疊加與拼接操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Java獲得一個(gè)數(shù)組的指定長(zhǎng)度排列組合算法示例

    Java獲得一個(gè)數(shù)組的指定長(zhǎng)度排列組合算法示例

    這篇文章主要介紹了Java獲得一個(gè)數(shù)組的指定長(zhǎng)度排列組合算法,結(jié)合實(shí)例形式分析了java排列組合相關(guān)數(shù)組遍歷、運(yùn)算操作技巧,需要的朋友可以參考下
    2019-06-06
  • Java面試之動(dòng)態(tài)規(guī)劃與組合數(shù)

    Java面試之動(dòng)態(tài)規(guī)劃與組合數(shù)

    這篇文章主要介紹了Java面試之動(dòng)態(tài)規(guī)劃與組合數(shù)的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • mongo分布式鎖Java實(shí)現(xiàn)方法(推薦)

    mongo分布式鎖Java實(shí)現(xiàn)方法(推薦)

    下面小編就為大家?guī)?lái)一篇mongo分布式鎖Java實(shí)現(xiàn)方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • Java選擇排序法以及實(shí)例詳解

    Java選擇排序法以及實(shí)例詳解

    在本篇文章里小編給大家整理了一篇關(guān)于Java選擇排序法以及實(shí)例內(nèi)容,并做了詳細(xì)分析,有興趣的朋友們可以跟著學(xué)習(xí)下。
    2022-11-11
  • Spring Boot使用Log4j2的實(shí)例代碼

    Spring Boot使用Log4j2的實(shí)例代碼

    這篇文章主要介紹了Spring Boot使用Log4j2的實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • Intellij IDEA 如何通過(guò)數(shù)據(jù)庫(kù)表生成帶注解的實(shí)體類(lèi)(圖文詳細(xì)教程)

    Intellij IDEA 如何通過(guò)數(shù)據(jù)庫(kù)表生成帶注解的實(shí)體類(lèi)(圖文詳細(xì)教程)

    這篇文章主要介紹了Intellij IDEA 如何通過(guò)數(shù)據(jù)庫(kù)表生成帶注解的實(shí)體類(lèi)(圖文詳細(xì)教程),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11

最新評(píng)論