动态SQL的 if 条件判断

错误方式一:
在mybatis的动态sql语句中使用<if>标签可以判断sql中的条件是否成立。

    <select id="getPerson" resultType="com.lzj.bean.Employee">
        select * from tbl_employee
        where
            <if test="id!=null">
                id=#{id}
            </if>
            <if test="lastName!=null and lastName!=''">
                and last_name like #{lastName}
            </if>
            <if test="email!=null and email.trim()!=''">
                and email=#{email}
            </if> 
            <if test="gender==0 or gender==1">
                and gender=#{gender}
            </if>
     </select>

在上面的动态sql语句中存在一个问题,当第一条sql判断语句

   <if test="id!=null">
                id=#{id}
            </if>

失败时,即id值为null,而lastName、email和gender判断成功后,最后sql语句就会变为:
select * from tbl_employee where and last_name like #{lastName} and email=#{email} and gender=#{gender}
where后面多一个and,执行sql时会失败。

改正方式一:
在where条件后面加了一条判断1=1,然后在id的判断后加上and关键字,这样当下面if条件中的任何一个判断失败后,都不会影响整个sql语句。

 <select id="getPerson" resultType="com.lzj.bean.Employee">
        select * from tbl_employee
        where 1=1
            <if test="id!=null">
                and id=#{id}
            </if>
            <if test="lastName!=null and lastName!=''">
                and last_name like #{lastName}
            </if>
            <if test="email!=null and email.trim()!=''">
                and email=#{email}
            </if> 
            <if test="gender==0 or gender==1">
                and gender=#{gender}
            </if>
     </select

错误方式二:
有些人习惯在每个if判断中的数据库字段的后面加and关键字,例如

<select id="getPerson" resultType="com.lzj.bean.Employee">
        select * from tbl_employee
        where
            <if test="id!=null">
                id=#{id} and
            </if>
            <if test="lastName!=null and lastName!=''">
                last_name like #{lastName} and
            </if>
            <if test="email!=null and email.trim()!=''">
                email=#{email} and
            </if> 
            <if test="gender==0 or gender==1">
                gender=#{gender}
            </if>
     </select

但是上述情况存在一个弊端,当最后一个if判断gender失败时,sql语句就变成了:
select * from tbl_employee where id=#{id} and last_name like #{lastName} and email=#{email} and
where条件的最后多一个and,sql语句执行的时候也会失败。
改正方式二:
在最后一个if语句中库表字段后加and关键字,然后在最后加1=1判断

   <select id="getPerson" resultType="com.lzj.bean.Employee">
        select * from tbl_employee
        where
            <if test="id!=null">
                id=#{id} and
            </if>
            <if test="lastName!=null and lastName!=''">
                last_name like #{lastName} and
            </if>
            <if test="email!=null and email.trim()!=''">
                email=#{email} and
            </if> 
            <if test="gender==0 or gender==1">
                gender=#{gender} and
            </if>
            1=1
     </select

建议方式:习惯写法

<where><if> 进行组合,当条件不成立时,if条件后的内容包括and也不会存在,因此不会对整个sql语句产生影响。注意and关键字要放在每个<if>语句中的库表字段赋值的前面。因为,一旦判断不成功,<where> 会把对应的and关键字去掉(还有or关键字)。

<select id="getPerson" resultType="com.lzj.bean.Employee">
    select * from tbl_employee
    <where> AND delete_flag = 1
        <!-- test:判断表达式(OGNL)
        遇见特殊符号应该去写转义字符:&&、''等字符
        -->
        <if test="id!=null">
        AND   id=#{id}
        </if>
        <if test="lastName!=null and lastName!=''">
           AND  last_name like #{lastName}
        </if>
        <if test="email!=null and email.trim()!=''">
            AND  email=#{email}
        </if> 
        <!-- ognl会进行字符串与数字的转换判断  "0"==0 -->
        <if test="gender==0 or gender==1">
            AND  gender=#{gender}
        </if>
    </where>
    order by id desc //排序
 </select>

上述很多特殊字符可以写成转义的形式,例如

 <select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee">
    select * from tbl_employee
    <!-- where -->
    <where>
        <if test="id!=null">
            id=#{id}
        </if>
        <if test="lastName!=null &amp;&amp; lastName!=&quot;&quot;">
            and last_name like #{lastName}
        </if>
        <if test="email!=null and email.trim()!=&quot;&quot;">
            and email=#{email}
        </if> 
        <if test="gender==0 or gender==1">
            and gender=#{gender}
        </if>
    </where>
 </select>

注意<if>失败后, 关键字只会去掉库表字段赋值前面的and,不会去掉后面的and关键字,即注意,只会去掉<f>语句中的最开始的and关键字。所以下面的形式是不可取的

<select id="getPerson" resultType="com.lzj.bean.Employee">
    select * from tbl_employee
    <where>
    		delete_falt = 1    //根据删除标识为1的
        <if test="id!=null">
            id=#{id} and
        </if>
        <if test="lastName!=null and lastName!=''">
            last_name like #{lastName} and
        </if>
        <if test="email!=null and email.trim()!=''">
            email=#{email} and
        </if> 
        <if test="gender==0 or gender==1">
            gender=#{gender}
        </if>
    </where>

因为,失败后,`不会自动去掉后面的and关键字,这种形式与错误方式二原理相同。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值