天天看點

客觀看待mybatis 中使用 where 1=1

随便一翻,可以看到使用where 1=1 的人很多, 可能這已經是一個編碼習慣了。

客觀看待mybatis 中使用 where 1=1

那麼使用where 1=1 ,會怎麼樣麼 。

首先,先辟謠。  

客觀看待mybatis 中使用 where 1=1
客觀看待mybatis 中使用 where 1=1
客觀看待mybatis 中使用 where 1=1

where 1=1 不會導緻索引失效 !

where 1=1 不會導緻索引失效 !

where 1=1 不會導緻索引失效 !

客觀看待 :

為什麼會去寫這個where 1=1 ? 

WHERE 1=1 

示例:

<select id="queryList" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from user_info
    where 1=1

    <if test="type !=null">
        and TYPE = #{type}
    </if>
</select>      

可能很多人看到這,已經知道,其實mybatis有where 标簽是專門用于這種場景的。

而且絕大多數人都知道where标簽,隻是還是習慣使用 where 1=1 .

其實就是兩個點 :

1. 複制粘貼,随便哪個查詢都是if 标簽, 複制改一改, 為了不報錯,加上 where 1=1 ,完事。

2. 知道mysql 會将接收到的sql 指令做優化,這種where 1=1 是會被優化掉的,是以不影響。

不影響索引命中:

客觀看待mybatis 中使用 where 1=1

 不使用 where 1=1 ,能夠命中索引:

客觀看待mybatis 中使用 where 1=1

 使用 where 1=1 ,一樣命中索引:

客觀看待mybatis 中使用 where 1=1

是以再說一次 :  where 1=1 不會導緻索引失效 !

Mybatis where标簽

示例:

<select id="queryList" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from user_info
    <where>
        <if test="type !=null">
            and TYPE = #{type}
        </if>
    </where>
</select>      

 可以看到使用where标簽的話,第一個感覺就是,代碼順暢一點,但是多了一個where标簽的使用知識需要知道。

可以看到,我的示例,上面 where标簽  裡面 的第一個if标簽裡面 有寫 and 。

這個是沒影響的,mybatis也會幫我們做優化,第一個 and這種東西沒關系的。

因為多個if标簽同時存在的時候,隻要保證觸發了的标簽  兩兩之間是用 and 或者 or這些連接配接起來就行, 第一個會自動優化掉。當然這是mybatis幫我們做的事情。

我怎麼知道?看源碼看的 :

mybatis where标簽的源碼:

客觀看待mybatis 中使用 where 1=1

可以看到代碼裡面 where标簽 隻是定義了一下 所謂的字首list,實際上還是用的super。

繼承的父類,其實就是 trim 标簽。

是以我們使用where标簽寫的示例,也可以改成使用trim标簽 :

<select id="queryList" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List"/>
    from user_info
    <trim prefix="WHERE" prefixOverrides="AND | OR" >
        <if test="type !=null">
            and TYPE = #{type}
        </if>
    </trim>
    
</select>      

trim标簽 ,也可以瞄一眼源碼:

客觀看待mybatis 中使用 where 1=1

prefix:給trim标簽内sql語句加上字首

suffix:給trim标簽内sql語句加上字尾

prefixOverrides:去除多餘的字首内容,如:prefixOverrides=“AND”,去除trim标簽内sql語句多餘的字首"AND"

suffixOverrides:去除多餘的字尾内容,如:suffixOverrides=",",去除trim标簽内sql語句多餘的字尾","

那麼mybatis怎麼去處理這個where标簽(包括任何其他标簽)的呢? 其實mybatis源碼上有相關的測試函數,也可以看的是怎麼給我們如何解析where标簽,最後拼接成sql的。

感興趣的可以自己看看(如果你自己有想法,其實可以自己定義自己的一套規則,反正最終是解析拼接出sql語句。):

客觀看待mybatis 中使用 where 1=1

 值得思考的問題

扯遠了,那麼回到正題, 客觀看待使用 where 1=1 .

上面列了一些where标簽的源碼,為什麼我要列這些。

其實就是為了引出一個值得思考斟酌的問題?

使用 where 1=1 ,mysql底層會幫我們優化, 不影響索引。

使用where标簽, 則需要 代碼層面 幫我們解析。