MyBatis 05-动态 SQL
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
要求的判断表达式,表达式的结果可以是 true
或 false
,所有非 0 的值都为 true,只有 0 为 false。
- 判断条件
property != null
或property == null
,适用于任何类型的字段,用于判断属性值是否为空。 - 判断条件
property != ''
或property == ''
,仅适用于String
类型。 and
和or
,嵌套的判断可以使用小括号分组。
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 表达式,常用的表达式如下:
- e1 or e2
- e1 and e2
- e1 == e2 或 e1 eq e2
- e1 != e2 或 e1 neq e2
- e1 lt e2:小于
- e1 lte e2:小于等于,gt(大于),gte(大于等于)
- e1 + e2:+-*/%
- !e 或 not e:非、取反
e.method(args)
:调用对象方法,list.size() > 0
e.property
:对象属性值e1[e2]
:按索引取值(List、数组和 Map)@class@method(args)
:调用类的静态方法@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" 转载请保留原文链接及作者。