随便一翻,可以看到使用where 1=1 的人很多, 可能這已經是一個編碼習慣了。
那麼使用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 是會被優化掉的,是以不影響。
不影響索引命中:
不使用 where 1=1 ,能夠命中索引:
使用 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标簽的源碼:
可以看到代碼裡面 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标簽 ,也可以瞄一眼源碼:
prefix:給trim标簽内sql語句加上字首
suffix:給trim标簽内sql語句加上字尾
prefixOverrides:去除多餘的字首内容,如:prefixOverrides=“AND”,去除trim标簽内sql語句多餘的字首"AND"
suffixOverrides:去除多餘的字尾内容,如:suffixOverrides=",",去除trim标簽内sql語句多餘的字尾","
那麼mybatis怎麼去處理這個where标簽(包括任何其他标簽)的呢? 其實mybatis源碼上有相關的測試函數,也可以看的是怎麼給我們如何解析where标簽,最後拼接成sql的。
感興趣的可以自己看看(如果你自己有想法,其實可以自己定義自己的一套規則,反正最終是解析拼接出sql語句。):
值得思考的問題
扯遠了,那麼回到正題, 客觀看待使用 where 1=1 .
上面列了一些where标簽的源碼,為什麼我要列這些。
其實就是為了引出一個值得思考斟酌的問題?
使用 where 1=1 ,mysql底層會幫我們優化, 不影響索引。
使用where标簽, 則需要 代碼層面 幫我們解析。