MyBatis入门之 动态SQL

动态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>

在这里插入图片描述
查询会出现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>

在这里插入图片描述
用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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值