Mybatis官方文档-动态SQL
动态SQL是MyBatis强大的特性之一。如果自己拼接SQL会经常遇到忘记空格,逗号的情况,但是使用mybatis就可以避免这些情况。
常见的标签有:
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
if
一般是使用在where子句中:
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>
多项选择:
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
choose、when、otherwise
<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
一般的问题,前面的可以解决,但是遇到下面这个情况就会出现问题:
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
如果后面的if全部失效,那么就会变成
SELECT * FROM BLOG
WHERE
很明显这个语句是不符合语法的。
如果第一个IF失效,那么就变成了:
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’
这又多了一个AND,也是不符合语法的。
这个时候就可以使用
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
这个标签可以解决没有IF或者多了AND的问题。
这个可以和trim等价起来,trim是可以自定义前缀后缀等等的。
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
上面这个语句,代表前缀是WHERE,如果前缀出现了 AND 或者OR 就会被覆盖掉,同理可以得到
<trim prefix="SET" suffixOverrides=",">
...
</trim>
如果后缀是”,“那么就覆盖掉。
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
set用法
foreach
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
Tips:你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
浙公网安备 33010602011771号