<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MyBatis 中為什么不建議使用 where 1=1?

          共 1929字,需瀏覽 4分鐘

           ·

          2022-02-11 10:33

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

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


          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)單的方式就是將它直接從代碼中刪除了,如下代碼所示:

          "1.0"?encoding="UTF-8"?>
          "-//mybatis.org//DTD?Mapper?3.0//EN"?"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
          "com.example.demo.mapper.UserMapper">
          ????"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>
          ????

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

          但這樣就沒(méi)問(wèn)題了嗎?我們直接來(lái)看結(jié)果,當(dāng)包含參數(shù) name 查詢時(shí),結(jié)果如下:一切順理成章,完美的一塌糊涂。?

          然而,當(dāng)省略 name 參數(shù)時(shí)(因?yàn)?name 為非必要參數(shù),所以可以省略),竟然引發(fā)了以下異常:又或者只有 password 查詢時(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)題就解決了,如下代碼所示:


          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ù)(查詢所有數(shù)據(jù)),如下圖所示:生成的 SQL 語(yǔ)句如下:

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

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

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

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

          用法解析

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

          首先,標(biāo)簽會(huì)判斷,如果沒(méi)有任何參數(shù),則不會(huì)在 SQL 語(yǔ)句中拼接 where 查詢,反之才會(huì)拼接 where 查詢;其次在查詢的標(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è)而不為呢?

          程序汪資料鏈接

          程序汪接的7個(gè)私活都在這里,經(jīng)驗(yàn)整理

          Java項(xiàng)目分享 最新整理全集,找項(xiàng)目不累啦 06版

          堪稱神級(jí)的Spring Boot手冊(cè),從基礎(chǔ)入門(mén)到實(shí)戰(zhàn)進(jìn)階

          臥槽!字節(jié)跳動(dòng)《算法中文手冊(cè)》火了,完整版 PDF 開(kāi)放下載!

          臥槽!阿里大佬總結(jié)的《圖解Java》火了,完整版PDF開(kāi)放下載!

          字節(jié)跳動(dòng)總結(jié)的設(shè)計(jì)模式 PDF 火了,完整版開(kāi)放下載!

          歡迎添加程序汪個(gè)人微信 itwang008? 進(jìn)粉絲群或圍觀朋友圈

          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲成人电影无码 | 亚洲黄色电影怎么 | 亚洲黄色视频网站在线观看 | 日韩在线观看第一页 | 欧美在线观看网址 |