MyBatis 中的动态 SQL 的相关使用方法

   为什么会有动态SQL,把SQL写死不是比较方便吗?其实有很多的举例,这里我那一个常见的来说,像我们用户注册,会有必填字段和非必填字段,有些传来的参数不一样,那对应的SQL也不一样,因此,在这些的场景底下我们需要使用动态SQL来完成。

  这里动态SQL我是使用XML的办法进行说明,因为使用注解不方便,而且不好观察哪里有误。这里我会先从一些常用的标签的介绍来对动态SQL进行使用的讲解。

1.1 <if>标签

    <insert id="insertByCondition">
        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>
        ) 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>
        )
    </insert>

 

  从上述代码可以简单看出来,<if> 标签是一个<if test = "xxxx">xxxx</if>的结构,然后另一个是运行后的结果,这里发现如果if里面都有值的话,可以完好的插入,但是它就一定没问题吗?下面一个图我就简单注释掉几个来,实验一下。

  从上图可以简单的看错来,它是一个BadSql因为我们注掉了username导致,多了一个逗号那怎么样才能避免上述情况呢?那就要引入新的注解。

1.2<trim> 标签

  这里我们先简单介绍一下<trim>标签里面几个常见的属性:
     1. prefix:表示整个语句块,以prefix的值作为前缀。

     2. suffix:表示整个语句块,以suffix的值作为后缀。

     3. prefixOverrides:表示整个语句块要去除掉前缀。

     4. suffixOverrides:表示整个语句块要去掉后缀。

<insert id="insertByCondition">
        insert into userinfo
        <trim prefix="(" suffix=")" prefixOverrides=",">
            <if test="username != null">
                username
            </if>
            <if test="password != null">
                ,password
            </if>
            <if test="gender != null">
                ,gender
            </if>
            <if test="age != null">
                ,age
            </if>
        </trim>
        values
        <trim prefix="(" suffix=")" prefixOverrides=",">
            <if test="username != null">
                #{username}
            </if>
            <if test="password != null">
                ,#{password}
            </if>
            <if test="gender != null">
                , #{gender}
            </if>
            <if test="age != null">
                ,#{age}
            </if>

        </trim>
    </insert>

  上述因为username是不能为空,因此我把注掉username改为注掉gender,可以发现在<if>标签里面的问题给解决了。

1.3  <where>标签

<select id="queryUserByCondition" resultType="com.jincheng.mybatisdemo.model.UserInfo">
        select * from userinfo
        <where>
            <if test="age != null">
                age = #{age}
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="deleteFlag">
                and delete_flag = #{deleteFlag}
            </if>
        </where>
    </select>
    <select id="queryUserByCondition" resultType="com.jincheng.mybatisdemo.model.UserInfo">
        select * from userinfo
        <trim prefix="where" prefixOverrides="and">
            <if test="age != null">
                age = #{age}
            </if>
            <if test="gender != null">
                and gender = #{gender}
            </if>
            <if test="deleteFlag">
                and delete_flag = #{deleteFlag}
            </if>
        </trim>
    </select>

  通过上面可以发现第一个是使用<where>标签进行写的,而另一个是通过使用<trim>标签进行写的。可以简单比对一下<where>标签,生成where关键字,并且去除最前面的and 或者 or,如果where标签代码块,没有一个查询条件,会省略掉where关键字。也可以使用<trim prefix="where" prefixOverrides="and">替换,但是这种情况下,子元素没有内容时,where关键字也会保留。

1.4 <set>标签

<update id="updateByCondition">
        update userinfo
        <set>
            <if test="password != null">
                password = #{password},
            </if>
            <if test="age != null">
                age = #{age},
            </if>
            <if test="gender != null">
                gender = #{gender}
            </if>
        </set>
            where id = #{id}
    </update>

  这里<set>标签,生成set关键字,去掉整个代码块后面的逗号。如果使用<trim prefix="set" suffixOverrides=",">可以进行替换。

1.5 <foreach>标签

  简单来说一下<foreach>标签里面的属性:

      1. collection:绑定方法参数中的集合,如LIst,Set,Map或数组对象

      2. item:遍历是的每一个对象

      3. open:语句块开头的字符串

      4. close:语句块结束的字符串

      5. separator:每次遍历之间间隔的字符串。

一般用在批量删除中等等。

    <delete id="batchDelete">
        delete  from userinfo
        where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </delete>

1.6 <inlcude>标签

  这个标签用于在xml映射文件中配置的SQL,有时可能会存在很多重复的片段,此时就会在很多多余的代码。

  这里我们需要对重复的代码片段进行抽取,将其通过<sql>标签封装到一个SQL片段,然后通过<include>标签进行引用:

        1.<sql> : 定义可重用的SQL片段

        2. <include>:通过属性refid,指定包含的SQL片段。

    <sql id="selectAll">
        select * from userinfo
    </sql>

    <select id="select" resultType="com.jincheng.mybatisdemo.model.UserInfo">
        <include refid="selectAll"></include>
    </select>

相关推荐

  1. MyBatis 动态 SQL 是什么? 如何使用动态 SQL

    2024-04-13 05:02:03       44 阅读
  2. MyBatis动态SQL

    2024-04-13 05:02:03       54 阅读
  3. MyBatis 之十:MyBatis 框架注解动态 SQL

    2024-04-13 05:02:03       43 阅读
  4. MyBatisMybatis动态SQL——bind标签

    2024-04-13 05:02:03       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-13 05:02:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-13 05:02:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-13 05:02:03       87 阅读
  4. Python语言-面向对象

    2024-04-13 05:02:03       96 阅读

热门阅读

  1. hive sql一直跑到reduce=100%,然后挂掉重新跑

    2024-04-13 05:02:03       96 阅读
  2. 【CMake】CMake打包Dll

    2024-04-13 05:02:03       34 阅读
  3. python内置函数compile(),complex()详解

    2024-04-13 05:02:03       34 阅读
  4. AWS被误扣费了,怎么解决?

    2024-04-13 05:02:03       39 阅读
  5. python字符切片的规则

    2024-04-13 05:02:03       43 阅读
  6. 一个神奇的 Python 库——Ray

    2024-04-13 05:02:03       45 阅读
  7. HTML5新增元素

    2024-04-13 05:02:03       76 阅读
  8. lisp学习历程

    2024-04-13 05:02:03       41 阅读
  9. 我的lisp学习历程

    2024-04-13 05:02:03       35 阅读