Mybatis中where標簽與if標簽結(jié)合使用詳細說明
前言
由于不小心將and或者or寫在了語句后面,導(dǎo)致mybatis無法自主判別,這種問題在新上手的同學(xué)中很是常見。下面我們探討一下,在哪些情況下Mybatis無法判斷動態(tài)SQL語句中的and或者or。
使用<where>標簽
select篩選出視圖對象的參數(shù),用于給前端返回頁面參數(shù)使用。
<sql id="selectFileVo">
select file_id,
uuid,
file_name,
file_url,
status,
create_time,
update_time
from file
</sql>
以下代碼格式是正確,我們先觀察下and或者or的位置。
<select id="selectFileList" parameterType="File" resultMap="FileResult">
<include refid="selectFileVo"/>
<where>
<if test="fileName != null and fileName != ''">
and file_name like concat('%', #{fileName}, '%')
</if>
<if test="status != null and status != ''">
and status = #{status}
</if>
<if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''">
and create_time between #{params.beginCreateTime} and #{params.endCreateTime}
</if>
</where>
</select>
再看一下錯誤的寫法;
<select id="selectFileList" parameterType="File" resultMap="FileResult">
<include refid="selectFileVo"/>
<where>
<if test="fileName != null and fileName != ''">
file_name like concat('%', #{fileName}, '%') and
</if>
<if test="status != null and status != ''">
status = #{status} and
</if>
<if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''">
create_time between #{params.beginCreateTime} and #{params.endCreateTime}
</if>
</where>
</select>
這時候運行該代碼,當beginCreateTime或endCreateTime為空時,我們會發(fā)現(xiàn)報錯SQL執(zhí)行異常,原因是where多了一個and。
總結(jié)
當<if>標簽判斷失敗后, <where> 標簽關(guān)鍵字可以自動去除掉庫表字段賦值前面的and,不會去掉語句后面的and關(guān)鍵字,即<where> 標簽只會去掉<if> 標簽語句中的最開始的and關(guān)鍵字。所以上面的寫法(and寫在后面)是不符合mybatis規(guī)范的。
不使用<where>標簽
當不使用<where>標簽時,正確的寫法可以參考以下代碼:
<select id="selectFileList" parameterType="File" resultMap="FileResult">
<include refid="selectFileVo"/>
where 1=1
<if test="fileName != null and fileName != ''">
and file_name like concat('%', #{fileName}, '%')
</if>
<if test="status != null and status != ''">
and status = #{status}
</if>
<if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''">
and create_time between #{params.beginCreateTime} and #{params.endCreateTime}
</if>
</select>
此時我們發(fā)現(xiàn)and是寫在前面的,同時增加了1=1條件。
如果我們?nèi)サ?code>1=1條件,同時去掉第一個<if>標簽的and。
<select id="selectFileList" parameterType="File" resultMap="FileResult">
<include refid="selectFileVo"/>
where
<if test="fileName != null and fileName != ''">
file_name like concat('%', #{fileName}, '%')
</if>
<if test="status != null and status != ''">
and status = #{status}
</if>
<if test="params.beginCreateTime != null and params.beginCreateTime != '' and params.endCreateTime != null and params.endCreateTime != ''">
and create_time between #{params.beginCreateTime} and #{params.endCreateTime}
</if>
</select>
這種情況下,當fileName為空時,sql語句中會出現(xiàn)where and這種錯誤的語法,最終導(dǎo)致sql執(zhí)行異常。所以正確的代碼中,使用1=1條件,當fileName為空時,sql語句就會變成where 1=1 ,后面接不接and都能正確執(zhí)行。
在不使用<where>標簽的情況下,and寫在后面,在where條件最后增加1=1判斷,原理和上面一樣,這里就不再贅述了。
總結(jié)
到此這篇關(guān)于Mybatis中where標簽與if標簽結(jié)合使用的文章就介紹到這了,更多相關(guān)Mybatis使用where標簽與if標簽內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實戰(zhàn)之醫(yī)院管理系統(tǒng)的實現(xiàn)
這篇文章主要介紹了如何利用Java實現(xiàn)醫(yī)院管理系統(tǒng),文中用到的技術(shù)有:SpringBoot、Layui、Freemaker等,感興趣的同學(xué)可以了解一下2022-04-04
SpringBoot3各種配置的優(yōu)先級對比小結(jié)
SpringBoot3提供了多種配置來源以滿足不同場景下的需求,本文詳細介紹了SpringBoot3中的配置優(yōu)先級對比小結(jié),具有一定的參考價值,感興趣的可以了解一下2024-12-12

