MyBatis - 动态SQL

前言

我们在某网站填写个人信息时,时常会遇到可以选填的空(即可填,可不填),由于之前讲过的Java中的SQL语句都是固定的,且我们不可能对所有情况都写出与之对应的插入语句(太过繁琐),所以这里就引入了动态SQL。

一,<if>标签

可以通过判断当前传入的参数是否为null,来删减对应的参数。

@Mapper
public interface UserInfoXmlMapper {
    Integer insertUserInfo(UserInfo userInfo);
}
    <insert id="insertUserInfo" useGeneratedKeys="true" keyProperty="id">
        insert into userInfo
        (username,password,age,
         <if test="gender!=null">
             gender,
         </if>
         phone)
        values
        (#{username},#{password},#{age},
         <if test="gender!=null">
             #{gender},
         </if>
        #{phone})
    </insert>

二,<trim> 标签

但是如果光使用<if>标签可能会出现错误,比如:

<insert id="insertUserInfo" useGeneratedKeys="true" keyProperty="id">
        insert into userInfo
        (
         <if test="username!=null">
             username,
         </if>
         <if test="password!=null">
             password,
         </if>
         <if test="age!=null">
             age,
         </if>
         <if test="gender!=null">
             gender,
         </if>
         <if test="phone!=null">
             phone
         </if>
         )
        values
        (
        <if test="username!=null">
            #{username},
        </if>
        <if test="password!=null">
            #{password},
        </if>
        <if test="age!=null">
            #{age},
        </if>
        <if test="gender!=null">
            #{gender},
        </if>
        <if test="phone!=null">
            #{phone}
        </if>
        )
    </insert>

这时就要使用<trim>标签,该标签有四个属性:

  • prefix:表示整个语句块,以 prefix 的值作为前缀
  • suffix:表示整个语句块,以 suffix 的值作为后缀
  • prefixOverrides:表示整个语句块要删去的前缀
  • suffixOverrides:表示整个语句块要删去的后缀
    <insert id="insertUserInfo" useGeneratedKeys="true" keyProperty="id">
        insert into userInfo
        <trim prefixOverrides="," suffixOverrides="," prefix="(" suffix=")">
            <if test="username!=null">
                username,
            </if>
            <if test="password!=null">
                password,
            </if>
            <if test="age!=null">
                age,
            </if>
            <if test="gender!=null">
                gender,
            </if>
            <if test="phone!=null">
                phone
            </if>
        </trim>
        values
        <trim prefixOverrides="," suffixOverrides="," prefix="(" suffix=")">
            <if test="username!=null">
                #{username},
            </if>
            <if test="password!=null">
                #{password},
            </if>
            <if test="age!=null">
                #{age},
            </if>
            <if test="gender!=null">
                #{gender},
            </if>
            <if test="phone!=null">
                #{phone}
            </if>
        </trim>
    </insert>

解释各个属性的作用:

  • prefix:在开始部分加上(
  • suffix:在结束部分加上 )
  • prefixOverrides:如果在所以<if>标签中内容拼接之后,以 ',' 开头,那么就将它删除
  • suffixOverrides:如果在所以<if>标签中内容拼接之后,以 ',' 结尾,那么就将它删除

后两个属性就避免出现上述SQL语句的问题

三,<where> 标签

在where条件查询中,我们的查询条件也有可能为null,所以也需要用到<if>标签,也就是说这里也会出现上述问题,只不过这里多出来的是and / or,这时就需要使用<where>标签来帮我们删除where语句开头的 and / or。注:虽然使用<trim>标签也能达到上述效果,但是如果where查询中的所有参数都为 null 时,<where>标签能将自己本身给删除,而<trim>标签仍会保留where。

    <select id="queryUserList" resultType="com.example.javaeespringioc.controller.UserInfo">
        select * from userInfo
        <where>
            <if test="username!=null">
                username = #{username}
            </if>
            <if test="gender!=null">
                and gender = #{gender}
            </if>
        </where>
    </select>

四,<set> 标签

<set>标签也是删除因<if>标签产生的多余的 ',' ,它是可以使用<trim>标签替代的

    <update id="updateUserInfo">
        update userInfo
        <set>
            <if test="username!=null">
                username = #{username},
            </if>
            <if test="password!=null">
                password = #{password}
            </if>
        </set>
        where id = #{id}
    </update>

五,<foreach>标签

我们SQL中有这样的语句:delete from userinfo where id in (1,2,3,4,5),这无法使用之前的内容来表示,这时就会用到<foreach>标签,它有以下5个属性:

  • collections:绑定参数中集合,如 List,Set,Map 或 数组对象
  • item:遍历集合中的对象,类似于Java中,for(int x : nums) 中的 x
  • open:语句开头的字符串
  • close:语句结尾的字符串
  • separator:每个元素之间使用separator间隔开来
    <delete id="deleteUserInfo">
        delete from userInfo where id in
        <foreach collection="idx" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>

六,<include>标签

xml中的配置的SQL语句可能会存在很多重复的片段,我们可以对重复的片段进行抽取,通过<sql>标签进行封装,然后再通过<include>标签进行引用。

    <sql id="allColumn">
        id, username, password, age, gender, phone
    </sql>

    <select id="queryUserList" resultType="com.example.javaeespringioc.controller.UserInfo">
        select
        <include refid="allColumn"></include>
        from userInfo
        <where>
            <if test="username!=null">
                username = #{username}
            </if>
            <if test="gender!=null">
                and gender = #{gender}
            </if>
        </where>
    </select>

七,<script>标签

上述6个标签都是通过.xml文件来实现动态SQL,那么我们注解如何来实现动态SQL呢?就是使用<script>标签,代码如下:

    @Select("<script>" +
            "select * from userInfo " +
            "<where>" +
            "<if test='username!=null'>" +
            "username = #{username} " +
            "</if>" +
            "<if test='gender!=null'>" +
            "and gender = #{gender}" +
            "</if>" +
            "</where>" +
            "</script>")
    List<UserInfo> queryBy(@Param("username") String username, @Param("gender") Integer gender);

注意:注解中的是字符串,所以要注意字符串拼接时的空格,单双引号的问题。且使用注解方式如果出错,报错信息不会告诉你哪里出问题了,所以不推荐使用该方法!!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一叶祇秋

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

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

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

打赏作者

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

抵扣说明:

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

余额充值