【MyBatis】如何使用“动态SQL”(不用找了,这一篇足矣)

目录

一、if标签

二、where标签

三、trim标签

*四、choose、when、otherwise

五、foreach标签

*六、sql标签

七、set标签


一、if标签

        if,通过test属性中的表达式判断标签中的内容是否有效(有效才将if里面的内容拼接到sql中);一般用于用户在选填项中进行描述;

例如:在员工表中,根据姓名,年龄,性别查询员工信息(并且名字、年龄、姓名、若任意一个选填项为空,就不根据此条信息进行查询)

    <select id="getEmpByCondition" resultType="Emp">
        select * from emp where
        <if test="empName != null and empName != ''">
            emp_name = #{empName}
        </if>
        <if test="age != null and age != ''">
            and age = #{age}
        </if>
        <if test="gender != null and gender != ''">
            and gender = #{gender}
        </if>
    </select

if语句会遇到的问题:

        若empName,age,gender其中任意一项为空,都可能会导致sql语句语法错误,例如,empName为空,sql语句就变成了select * from emp where and age = ? and gender = ?;显然这里的where后面紧跟了一个and,这是错误的;另外,若这三个属性都为空,sql语句就变成了select * from emp where;这里多了一个where也是错的,那么该怎么办呢?

正确写法如下:

    <select id="getEmpByCondition" resultType="Emp">
        select * from emp where 1=1
        <if test="empName != null and empName != ''">
            and emp_name = #{empName}
        </if>
        <if test="age != null and age != ''">
            and age = #{age}
        </if>
        <if test="gender != null and gender != ''">
            and gender = #{gender}
        </if>
    </select>

解释:

        只需要在where后面加上一个1=1的恒成立条件(辅助拼接后面的and,某些情况下让where有意义),并且在每一个if的sql前面都加上一个and即可,这个时候,无论哪个if不成立,或者是都不成立,sql语句都不会出现语法错误;

这里其实还有第二种解决策略,就要用到动态sql中的另一个标签where~往下看


二、where标签

是 trim 标签的另一种写法。

where标签功能:

a.若where标签中有条件成立,会自动生成where关键字;

b.会自动将where标签中,配合 if 一起使用,并且会根实际场景,删除最前面的and去掉(注意不会删除最后面的);

c.若where标签中没有任何一个条件成立,则where没有任何功能;

where标签的使用:只需要将对应的if标签包裹起来即可;

例如:在员工表中,根据姓名,年龄,性别查询员工信息

    <select id="getEmpByCondition" resultType="Emp">
        select * from emp
        <where>
            <if test="empName != null and empName != ''">
                emp_name = #{empName}
            </if>
            <if test="age != null and age != ''">
                and age = #{age}
            </if>
            <if test="gender != null and gender != ''">
                and gender = #{gender}
            </if>
        </where>
    </select>

若emp_name为null,where标签就会去除后面的and标签,效果如下:

若全为空,where标签就不起作用,效果如下:


三、trim标签

trim标签的作用实际上就是他的四个属性:

prefix, suffix:在trim标签中内容的最前面或最后面添加指定内容;

prefixOverrides, suffixOverrides:在trim标签中内容最前面或最后面去掉指定内容(如果有,就去掉,如果没有就不进行操作);

例如:在员工表中,根据姓名,年龄,性别查询员工信息(去掉前后多余的and,并指定添加where)

    <select id="getEmpByCondition" resultType="Emp">
        select * from emp
        <trim prefix="where" suffixOverrides="and">
            <if test="empName != null and empName != ''">
                emp_name = #{empName} and
            </if>
            <if test="age != null and age != ''">
                age = #{age} and
            </if>
            <if test="gender != null and gender != ''">
                gender = #{gender}
            </if>
        </trim>
    </select>

另外,如果trim标签按如下写法,那么它起到的作用和 where 标签的效果则是一模一样(where 和 trim标签的区别)!!

        <trim prefix="where" prefixOverrides="and"></trim>


*四、choose、when、otherwise

他就相当于Java中的switch语句一样:

choose就相当于switch;

when就相当于case:...break,可以有多个,满足任意一个条件就会后面的就都不执行了;

otherwise就相当于default,最多设置一个,所有when都不满足就会执行他;

例如:在员工表中,根据姓名,年龄,性别查询员工信息(查询满足任意一个属性即可)

    <select id="getEmpByChoose" resultType="Emp">
        select * from emp
        <where>
            <choose>
                <when test="empName != null and empName != ''">
                    emp_name = #{empName}
                </when>
                <when test="age != null and age != ''">
                    age = #{age}
                </when>
                <when test="gender != null and gender != ''">
                    gender = #{gender}
                </when>
            </choose>
        </where>
    </select>

五、foreach标签

      foreach简单来讲  就是一个循环,可以把我们想要循环的内容放入标签即可,同时通过几个属性控制循环:

collection:设置要循环的数组或集合(最好使用Parm注解在接口中标识,否则Mybatis会把这样一个集合放入Map中,规定list为键,以集合数据为值);

item:用来表示数组或集合中的每一个数据;

separator:循环中设置分隔符(会自动在你设置的分隔符前后加空格);

open:当前循环的所有内容以什么字符串为开始;

close:当前循环的所有内容以什么字符串为结束;

示例一(通过List集合批量增加):向emp表中插入多条数据

   <insert id="insertMoreEmp">
        insert into emp values
        <foreach collection="emps" item="emp" separator=",">
            (null, #{emp.empName}, #{emp.age}, #{emp.gender})
        </foreach>
    </insert>

执行结果:(例如插入三条数据)

示例二(批量删除) :删除emp中id为3,4的数据

    <delete id="deleteMoreEmp">
        delete from emp where emp_id in
        (
            <foreach collection="empIds" item="empId" separator=",">
                #{empId}
            </foreach>
        )
    </delete>

执行结果:

 示例三(使用open,close属性)

    <insert id="insertMoreEmp">
        insert into emp values
        <foreach collection="emps" item="emp" separator=",">
            (null, #{emp.empName}, #{emp.age}, #{emp.gender})
        </foreach>
    </insert>

示例四(玩转foreach)

    <delete id="deleteMoreEmp">
        delete from emp where
        <foreach collection="empIds" item="empId" separator="or" open="(" close=")">
            emp_id = #{empId}
        </foreach>
    </delete>

*六、sql标签

sql标签可以记录一段sql,在需要用到的地方,使用include的标签进行引用

sql标签的属性id:表示这段sql的唯一身份标识;

include标签的属性 refid:标识引用sql标签的id,和sql标签的id是对应关系;

例如:记录emp_id, emp_name, age, gender这样个字段

    <sql id="empColumns">
        emp_id, emp_name, age, gender
    </sql>

    <select id="getEmpByConditionTwo" resultType="Emp">
        select <include refid="empColumns"></include> from emp
        <where>
            <if test="empName != null and empName != ''">
                emp_name = #{empName}
            </if>
            <if test="age != null and age != ''">
                and age = #{age}
            </if>
            <if test="gender != null and gender != ''">
                and gender = #{gender}
            </if>
        </where>
    </select>


七、set标签

是 trim 标签的另一种写法。

特征:

1.set 标签一般用在 update 的 sql 中。

2.set 标签通常搭配 if 标签一起使用。

3.set 标签会自动去除最后一个英文逗号。

例子如下:

    <update id="update2">
        update userinfo
        <set>
            <if test="username != null">
                username = #{username},
            </if>
            <if test="password != null">
                password = #{password},
            </if>
            <if test="photo != null">
                photo = #{photo}
            </if>
        </set>
        where id = #{id}
    </update>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈亦康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值