Mybatis动态SQL中—where标签与if标签的条件判断用法

        用<where>和<if> 进行组合,对<if>条件进行判断,一旦条件不成立时,<where> 标签会把对应的and关键字去掉(还有or关键字),if条件后的and不存在,因此就不会对整个sql语句产生影响。

注意and关键字要放在每个<if>语句中的库表字段赋值的前面。因为,一旦判断不成功,<where> 要把对应的and关键字去掉(还有or关键字)

一、首先我们看一种正确的建议使用方式:注意<where>中and位置

<select id="getPerson" resultType="com.lzj.bean.Employee">
    select * from tbl_employee
    <where>
        <!-- test:判断表达式(OGNL)
        遇见特殊符号应该去写转义字符:&&、''等字符
        -->
        <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> 
        <!-- ognl会进行字符串与数字的转换判断  "0"==0 -->
        <if test="gender==0 or gender==1">
            and gender=#{gender}
        </if>
    </where>
 </select>

注意,`<if>`失败后, `<where>` 关键字只会去掉库表字段赋值前面的and,不会去掉语句后面的and关键字,即注意,`<where>` 只会去掉`<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>
    </where>
 </select>

二、根据不同的写法习惯,有人可能会把 and 放在最后面,下面我们分别拆解用法的正确和错误方式。

1、错误方式一:

在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时会失败

1.1、改正方式一:

在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>

2、错误方式二:

有些人习惯在每个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语句执行的时候也会失败。

2.2、改正方式二:

在最后一个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>

3、建议方式(开篇的正确使用方式):

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

<select id="getPerson" resultType="com.lzj.bean.Employee">
    select * from tbl_employee
    <where>
        <!-- test:判断表达式(OGNL)
        遇见特殊符号应该去写转义字符:&&、''等字符
        -->
        <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> 
        <!-- ognl会进行字符串与数字的转换判断  "0"==0 -->
        <if test="gender==0 or gender==1">
            and gender=#{gender}
        </if>
    </where>
 </select>

上述很多特殊字符可以写成转义的形式,相比不同之处集中在<if>条件判断处,例如

 <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>`失败后, `<where>` 关键字只会去掉库表字段赋值前面的and,不会去掉后面的and关键字,即注意,`<where>` 只会去掉`<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>
    </where>
 </select>

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

------------------------------------------------------------------------------------以下无正文----------------------------------------------------------

注:仅供自己学习,记录问题和参考,共勉!

参考文章:

16、动态SQL之<where>、<if>条件判断_u010502101的博客-CSDN博客

### 回答1: MyBatis是一个流行的ORM框架,通过Mapper文件将Java对象映射到SQL语句。MyBatis的Mapper文件是一个XML文件,它包含了可以执行的SQL语句。动态SQLMyBatis的一个重要的功能,可以根据不同情况,生成不同的SQL语句,从而实现更加灵活的查询。 if标签MyBatis动态SQL的一种标签,它可以根据条件生成动态的SQL语句。if标签的语法如下: ``` <if test="condition1"> SQL语句 </if> ``` 其,test属性表示需要判断条件,可以是一个字符串表达式或者OGNL表达式。SQL语句则是当满足条件时需要执行的SQL语句。如果条件不满足,则不会执行这段SQL语句。 if标签可以包含多个嵌套的if标签,以实现更加复杂的条件判断。同时,还可以使用choose、when、otherwise标签结合if标签,实现更加灵活的条件判断。例如: ``` <select id="queryUsers" resultType="User"> SELECT * FROM users <where> <if test="username != null and username != ''"> AND username LIKE '%${username}%' </if> <if test="gender != null and gender != ''"> AND gender = #{gender} </if> <choose> <when test="orderBy == 'name'"> ORDER BY username </when> <when test="orderBy == 'age'"> ORDER BY age </when> <otherwise> ORDER BY id </otherwise> </choose> </where> </select> ``` 以上例子是一个查询用户的SQL语句,根据不同情况生成不同的SQL语句。其,if标签根据传入的参数判断是否需要加入username、gender的查询条件,choose标签根据orderBy的值,生成不同的排序条件。 if标签MyBatis动态SQL的重要功能之一,可以根据条件生成不同的SQL语句,从而实现更加灵活的查询。熟练掌握if标签的使用,可以使MyBatis开发更加高效和灵活。 ### 回答2: Mybatis是一款流行的Java ORM框架,它提供了许多方便的功能,其之一就是动态SQL。当我们需要根据不同的条件拼接SQL语句时,就可以使用动态SQL来实现。具体来说,if标签是其一种实现方式,下面将详解其用法。 if标签可以用于where、set、foreach等标签,用于判断当前条件是否成立,如果成立就拼接相应的SQL语句,否则不进行任何操作。其基本语法如下: <if test="condition"> SQL语句 </if> 其,test属性用于指定判断条件,可以是简单的表达式或者是复杂的逻辑语句。下面是一些常用的判断条件: 1. 判断参数是否为空 <if test="param != null"> SQL语句 </if> 2. 判断字符串是否为空 <if test="str != ''"> SQL语句 </if> 3. 判断是否相等 <if test="param == 'value'"> SQL语句 </if> 4. 判断是否大于 <if test="param > 10"> SQL语句 </if> 5. 判断是否包含 <if test="str.indexOf('value') != -1"> SQL语句 </if> 除了以上几种基本用法,if标签还可以嵌套使用,用于实现更复杂的判断逻辑。例如: <if test="param1 != null"> SQL语句 <if test="param2 != null"> SQL语句 </if> </if> 上述代码示例,如果param1不为空,就会拼接第一个SQL语句;如果param2也不为空,则会在第一个SQL语句之后再拼接第二个SQL语句。 总的来说,if标签Mybatis动态SQL的基础,能够帮助我们实现更加灵活的SQL拼接,提高代码的可读性和可维护性。学习和掌握其使用方法,对于开发高效、高质量的程序是非常有帮助的。 ### 回答3: MyBatis是一款非常优秀的Java持久层框架,提供了丰富的SQL查询方式。在进行SQL查询的时候,经常需要根据具体的条件组合而成不同的SQL语句。这个时候可以使用MyBatis动态SQL特性。在动态SQL,if标签是常用的一种方式。下面就来详解一下if标签用法。 if标签的作用:在SQL语句根据判断条件动态生成SQL语句。相当于Java的if语句。 if标签用法:在Mapper.xml文件,使用if标签包裹需要动态生成的SQL。if标签的属性为test,表示判断条件。属性值可以是任何符合OGNL规则的表达式,常见的有以下几种方式: 1. 如果条件不为空,则生成相应的SQL语句:<![CDATA[需要动态生成的SQL语句]]>。 例如: <select id="findUser" parameterType="User" resultMap="UserMap"> SELECT * FROM user <where> <if test="name != null and name != ''"> AND name = #{name} </if> </where> </select> 当调用findUser方法时,如果传入的name不为空,那么就会生成如下的SQL语句: SELECT * FROM user WHERE name = ? 2. 如果条件为true,则生成相应的SQL语句: 例如: <select id="findUsers" resultMap="UserMap"> SELECT * FROM user <where> <if test="name != null and name != ''"> AND name = #{name} </if> <if test="age != null"> AND age = #{age} </if> </where> </select> 当调用findUsers方法时,如果传入的name和age分别为"Tom"和20,那么就会生成如下的SQL语句: SELECT * FROM user WHERE name = 'Tom' AND age = 20 3. 如果条件为false,则不在生成相应的SQL语句: 例如: <select id="findUsers" resultMap="UserMap"> SELECT * FROM user <where> <if test="name != null and name != ''"> AND name = #{name} </if> <if test="age != null"> AND age = #{age} </if> </where> </select> 当调用findUsers方法时,如果传入的name为"Tom",age为空,那么就会生成如下的SQL语句: SELECT * FROM user WHERE name = 'Tom' if标签的嵌套: if标签可以进行嵌套,从而实现更加灵活的SQL生成方式。 例如: <select id="findUsers" resultMap="UserMap"> SELECT * FROM user <where> <if test="name != null and name != ''"> AND name = #{name} </if> <if test="age != null"> <if test="age < 18"> AND age < 18 </if> <if test="age >= 18 and age < 30"> AND age >= 18 AND age < 30 </if> <if test="age >= 30"> AND age >= 30 </if> </if> </where> </select> 当调用findUsers方法时,如果传入的name为空,age为25,那么就会生成如下的SQL语句: SELECT * FROM user WHERE age >= 18 AND age < 30 以上就是if标签用法详解。使用if标签可以让查询条件更加灵活、动态,深受开发者们的喜爱。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值