MyBatis 05-动态 SQL

  1. if
  2. choose, when, otherwise
  3. trim, where, set
  4. foreach
  5. bind
  6. 多数据库支持
  7. OGNL

http://www.broadview.com.cn/book/3643
https://mybatis.org/mybatis-3/zh/dynamic-sql.html

if

<if test="title != null and title != ''">
    AND title like #{title}
</if>

test 属性值是一个符合 OGNL 要求的判断表达式,表达式的结果可以是 truefalse,所有非 0 的值都为 true,只有 0 为 false。

  • 判断条件 property != nullproperty == null,适用于任何类型的字段,用于判断属性值是否为空。
  • 判断条件 property != ''property == '',仅适用于 String 类型。
  • andor,嵌套的判断可以使用小括号分组。

choose, when, otherwise

有点像 Java 中的 switch 语句。

如果提供了 title 就按 title 查找,提供了 author 就按 author 查找的情形,若两者都没有提供,就返回 featured=1 的。

<select id="findActiveBlogLike" resultType="Blog">
    SELECT * FROM BLOG WHERE state = 'ACTIVE'
    <choose>
        <when test="title != null">
            AND title like #{title}
        </when>
        <when test="author != null and author.name != null">
            AND author_name like #{author.name}
        </when>
        <otherwise>
            AND featured = 1
        </otherwise>
    </choose>
</select>

trim, where, set

where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入 WHERE 子句。而且,若语句的开头为 AND 或 OR ,where 元素也会将它们去除。

我们可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:

<!-- 这里的 AND 和 OR 后面的空格不能省略 -->
<trim prefix="WHERE" prefixOverrides="AND |OR ">
    ...
</trim>

set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。

set 元素等价的自定义 trim 元素:

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

trim 标签有如下属性:

  • prefix:当 trim 元素内包含内容时,会给内容增加 prefix 指定的前缀。
  • prefixOverrides:当 trim 元素内包含内容时,会把内容中匹配的前缀字符串去掉。
  • suffix:当 trim 元素内包含内容时,会给内容增加 suffix 指定的后缀。
  • suffixOverrides:当 trim 元素内包含内容时,会把内容中匹配的后缀字符串去掉。

foreach

<foreach item="item" index="index" collection="list"
    open="(" separator="," close=")">
        #{item}
</foreach>

foreach 包含以下属性:

  • collection:必填,为要迭代循环的属性名。
  • item:变量名,为从迭代对象中取出的每一个值。
  • index:索引的属性名,在集合数组情况下值为当前索引值,Map 类型时为 Map 的 key。
  • open:整个循环内容开头的字符串。
  • close:整个循环内容结尾的字符串。
  • separator:每次循环的分隔符。

批量新增并回写主键值,3.3.1 版本开始,只支持 MySQL。

<insert id="insertList" useGeneratedKeys="true" keyProperty="id">
    insert into sys user(
        user_name, user_password, user_email,
        user_info , head_img , create_time)
    values
    <foreach collection="list" item="user" separator=",">
        (
        #{user.userName}, #{user.userPassword}, #{user.userEmail},
        #{user.userlnfo}, #{user.headlmg, jdbcType=BLOB},
        #{user.createTime, jdbcType=TIMESTAMP})
    </foreach>
</insert>

bind

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
    <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
    SELECT * FROM BLOG
    WHERE title LIKE #{pattern}
</select>

多数据库支持

一个配置了 _databaseId 变量的 databaseIdProvider 可用于动态代码中,这样就可以根据不同的数据库厂商构建特定的语句。比如下面的例子:

<insert id="insert">
    <selectKey keyProperty="id" resultType="int" order="BEFORE">
        <if test="_databaseId == 'oracle'">
            select seq_users.nextval from dual
        </if>
        <if test="_databaseId == 'db2'">
            select nextval for seq_users from sysibm.sysdummy1"
        </if>
    </selectKey>
    insert into users values (#{id}, #{name})
</insert>

OGNL

MyBatis 的动态 SQL 和 ${} 形式的参数中都用到了 OGNL 表达式,常用的表达式如下:

  1. e1 or e2
  2. e1 and e2
  3. e1 == e2 或 e1 eq e2
  4. e1 != e2 或 e1 neq e2
  5. e1 lt e2:小于
  6. e1 lte e2:小于等于,gt(大于),gte(大于等于)
  7. e1 + e2:+-*/%
  8. !e 或 not e:非、取反
  9. e.method(args):调用对象方法,list.size() > 0
  10. e.property:对象属性值
  11. e1[e2]:按索引取值(List、数组和 Map)
  12. @class@method(args):调用类的静态方法
  13. @class@field:调用类的静态字段值

表达式 12 通常用于简化一些校验,如:

<if test="@tk.mybatis.util.StringUtil@isNotEmpty(userName)">
    and user_name like concat('%', #{userName}, '%')
</if>

StringUtil 类如下:

public class StringUtil {
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com

文章标题:MyBatis 05-动态 SQL

文章字数:1.2k

本文作者:Bin

发布时间:2019-10-09, 21:19:25

最后更新:2019-10-11, 19:12:27

原始链接:http://coolview.github.io/2019/10/09/MyBatis/MyBatis%2005-%E5%8A%A8%E6%80%81%20SQL/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录