欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MyBatis入门之 动态SQL

程序员文章站 2022-03-20 10:15:38
...

动态SQL是MyBatis的强大特性之一,极大的简化了我们拼装SQL的操作。
目录复制

if

使用动态SQL最常见的情景是根据条件包含where子句的一部分,比如:

<select id="getPersonByConditionIf" resultMap="myPerson">
    select * from person
    where age = 20
        <if test="name!=null and name != ''">
            and name like #{name}
        </if>
</select>

    这条语句提供了可选的查找文本功能,如果不传入“name”,name所有age=20的person都会返回,如果传入了name,name就会对name一列进行模糊查询并返回对应的person。
如果希望通过id和name两个参数进行可选搜索怎么办呢?只需要加入另一个条件即可。

<select id="getPersonByConditionIf" resultMap="myPerson">
    select * from person
    where age = 20
        <if test="name!=null and name != ''">
            and name like #{name}
        </if>
        <if test="id!=null and id!=''">
           and id = #{id}
        </if>
</select>

choose(otherwise when)

有时候,我们不想使用所有的条件,而是想从多个条件中选择一个使用。针对这种情况,mybatis提供了choose元素,它有点像Java中的switch语句。choose为switch,when为case,otherwise为default。

select id="getPersonByConditionChoose"  resultMap="myPerson">
    select * from person
    <where>
       /* 如果带了id就用id查,如果带了name就用name查询,只会进入其中的一个*/
        <choose>
            <when test="id != null">
                id =#{id}
            </when>
            <when test="name != null">
                name like #{name}
            </when>
            <otherwise>
                age = 18
            </otherwise>
        </choose>
    </where>
</select>

where

当if标签较多时,如果第一个字段值为null,如id = null,如下:

<select id="getPersonByConditionIf" resultMap="myPerson">
    select * from person
    where
        <if test="id!=null">
            id = #{id}
        </if>
        <if test="name!=null and name != ''">
            and name = #{name}
        </if>
        <if test="age!=null and age != ''">
            and age = #{age}
        </if>

</select>

MyBatis入门之 动态SQL
查询会出现where and 的情况,解决该情况除了将where 修改成 where 1=1之外,
还可以利用这个标签,如果标签返回的内容是以 and 或 or开头的,它就会被剔除。
将其修改为where标签,查看:

<select id="getPersonByConditionIf" resultMap="myPerson">
    select * from person
    <where>
        <if test="id!=null">
            id = #{id}
        </if>
        <if test="name!=null and name != ''">
            and name = #{name}
        </if>
        <if test="age!=null and age != ''">
            and age = #{age}
        </if>
    </where>
</select>

MyBatis入门之 动态SQL
用Where的时候, 把and写在前面

trim

trim字符串截取

<select id="getPersonByConditionTrim" resultMap="myPerson">
    <!-- 后面多出的and或者or where标签不能解决
     prefix="":前缀:trim标签体中是整个字符串拼串 后的结果。
             prefix给拼串后的整个字符串加一个前缀
     prefixOverrides="":
             前缀覆盖: 去掉整个字符串前面多余的字符
     suffix="":后缀
             suffix给拼串后的整个字符串加一个后缀
     suffixOverrides=""
             后缀覆盖:去掉整个字符串后面多余的字符-->

    select * from person
<!-- 自定义字符串的截取规则 -->

    <trim prefix="where" suffixOverrides="and">
        <if test="id != null">
            id =#{id} and
        </if>
        <if test="name!=null and name != ''">
            name like #{name} and
        </if>
        <if test="age != null and age != ''">
            age =#{age}
        </if>
    </trim>
</select>

set

使用 set+if 标签,如果某项为 null 则不进行更新,而是保持数据库原值。

<update id="updatePer">
    update person
    <set>
        <if test="name!=null">
            name = #{name}
        </if>
        <if test="age != null">
            age = #{age}
        </if>
    </set>
    where id = #{id}
</update>

foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候),
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符!
你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

<select id="getPerByConditionForeach" resultMap="myPerson">
    select * from person
    <!--
     collection:指定要遍历的集合:
         list类型的参数会特殊处理封装在map中,map的key就叫list
     item:将当前遍历出的元素赋值给指定的变量
     separator:每个元素之间的分隔符
     open:遍历出所有结果拼接一个开始的字符
     close:遍历出所有结果拼接一个结束的字符
     index:索引。遍历list的时候是index就是索引,item就是当前值
                   遍历map的时候index表示的就是map的key,item就是map的值

     #{变量名}就能取出变量的值也就是当前遍历出的元素
   -->
    <foreach collection="ids" item="item_id" separator=","
             open="where id in(" close=")">
        #{item_id}
    </foreach>
</select>

sql

当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。

<sql id="base_select">
    id,name,age
</sql>

<sql id="where_clause">

    <trim prefix="where" suffixOverrides="and">
        <if test="id != null">
            id =#{id} and
        </if>
        <if test="name!=null and name != ''">
            name like #{name} and
        </if>
        <if test="age != null and age != ''">
            age =#{age}
        </if>
    </trim>
</sql>

include

用于引用定义的常量

<select id="selectAll" resultMap="myPerson">
    select
    <include refid="base_select" />
    from person
    <include refid="where_clause"/>
</select>