Mybatis(六):动态 SQL

官方介绍:

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。  

通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。  

动态 SQL 元素和使用 JSTL 或其他类似基于XML的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

简单来讲,就是掌握四个标记

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach (之前讲过了)
一、<if>

选择性条件查找

    <!-- 选择性查找 -->
    <select id="selectSelective" resultMap="userMap" parameterType="cn.saytime.domain.User">
        SELECT *
        FROM tb_user
        WHERE 1 = 1
        <if test="username != null and username != '' ">
            and username LIKE CONCAT('%',#{username},'%')
        </if>
        <if test="age != null and age != '' ">
            and age = #{age}
        </if>
    </select>
二、<where>, <set>, <trim>

注意上面的 1=1,为了防止两个条件都不存在时,SQL执行报错,更好的解决方式是使用<where>

表示<where> 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。

    <select id="selectSelective" resultMap="userMap" parameterType="cn.saytime.domain.User">
        SELECT *
        FROM tb_user
        <where>
            <if test="username != null and username != '' ">
                username LIKE CONCAT('%',#{username},'%')
            </if>
            <if test="age != null and age != '' ">
                and age = #{age}
            </if>
        </where>
    </select>

选择性更新

注意<set>,能够过滤后面的逗号

    <!-- 选择性更新 -->
    <update id="updateSelective" parameterType="cn.saytime.domain.User">
        UPDATE tb_user
        <set>
            <if test="username != null and username != '' ">
                username = #{username},
            </if>
            <if test="age != null and age != '' ">
                age = #{age}
            </if>
        </set>
        WHERE id = #{id}
    </update>

如果上面两种都不满足要求的情况下,可以自定义<trim>

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  username = #{username}
  ...
</trim>


<trim prefix="SET" suffixOverrides=",">
  ...
</trim>
三、<choose>, <when>, <otherwise>
    <!-- 选择性查找2:有姓名则查找姓名,没有姓名看是否有年龄,有年龄查年龄,都没有默认查18岁以上的 -->
    <select id="selectSelective2" resultMap="userMap" parameterType="cn.saytime.domain.User">
        SELECT *
        FROM tb_user
        <where>
            <choose>
                <when test="username != null and username != '' ">
                    username LIKE CONCAT('%',#{username},'%')
                </when>
                <when test="age != null and age != '' ">
                    and age = #{age}
                </when>
                <otherwise>
                    and age > 18
                </otherwise>
            </choose>
        </where>
    </select>
四、<foreach>
<!-- 批量保存用户,并返回每个用户插入的ID -->
<insert id="batchSave" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO `test`.`tb_user`(`username`, age)
    VALUES
    <foreach collection="list" item="item" separator=",">
        (#{item.username}, #{item.age})
    </foreach>
</insert>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值