动态 SQL

根据不同的条件需要执行不同的 SQL 命令.称为动态 SQL

MyBatis 中动态 SQL 在 mapper.xml 中添加逻辑判断等.

OGNL 表达式,直接写 key 或对象的属性,不需要添加任何特殊符号。只能获取kye或对象的属性

If标签使用

判断是否满足条件,在动态 SQL 中所做的最通用的事情是包含部分 where 字句的条件。注意:在where子句后面如果直接使用if,会造成where and···语法错误,若where后面没有条件,则需要添加一个正确的等式(例如1=1)

1
2
3
4
5
6
7
8
9
10
<select id="selByAccinAccout" resultType="log"> 
select * from log where 1=1
<!-- OGNL 表达式,直接写 key 或对象的属性.不需要添加任 何特字符号 -->
<if test="accin!=null and accin!=''">
and accin=#{accin}
</if>
<if test="accout!=null and accout!=''">
and accout=#{accout}
</if>
</select>

where标签使用

当编写 where 标签时,如果内容中第一个是 and 去掉第一个and。配合if使用,比直接使用<-if>少写 where1=1

如果<-where>中有内容会生成 where 关键字,如果没有内容不生成 where 关键

1
2
3
4
5
6
7
8
9
10
11
<select id="selByAccinAccout" resultType="log"> 
select * from log
<where>
<if test="accin!=null and accin!=''">
and accin=#{accin}
</if>
<if test="accout!=null and accout!=''">
and accout=#{accout}
</if> <
/where>
</select>

choose, when, otherwise使用

有时我们不想应用所有的条件, 相反我们想选择很多情况下的一种。 Java 中的 switch 和语句相似,MyBatis 提供 choose 元素。

我们来搜索当 title 提供时仅有 title 条件,当 author 提供时仅有 author 条件。如果二者都没提供,只返回 featured blogs(也许是由管理员策略地选择的结果列表,而不是返回大量没有意义的随机博客结果列表)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<select id="findActiveBlogLike" 
parameterType="Blog" 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>

set标签使用

作用:去掉最后一个逗号。如果<-set>里面有内容生成 set 关键字,没有就不生成

1
2
3
4
5
6
7
8
9
10
<update id="upd" parameterType="log" > 
update log <set> id=#{id},
<if test="accIn!=null and accIn!=''">
accin=#{accIn},
</if>
<if test="accOut!=null and accOut!=''">
accout=#{accOut},
</if> </set>
where id=#{id}
</update

id=#{id} 目的防止中没有内容,mybatis 不生成 set 关键字,如果修改中没有 set 从句 SQL 语法错误.

trim标签使用

prefix 在前面添加内容

prefixOverrides 去掉前面内容

suffix 在后面添加内容

suffixOverrieds 去掉后面内容

执行顺序:去掉内容后添加内容

1
2
3
4
5
6
<update id="upd" parameterType="log"> 
update log
<trim prefix="set" suffixOverrides=","> a=a,
</trim>
where id=100
</update>

bind标签使用

作用:给参数重新赋值

使用场景:模糊查询。原内容前或后添加内容

1
2
3
4
<select id="selByLog" parameterType="log" resultType="log"> 
<bind name="accin" value="'%'+accin+'%'"/>
select * from log where accin like #{accin}
</select>

foreach标签

循环参数内容,还具备在内容的前后添加内容,还具备添加分隔符功能.

适用场景:in 查询中。批量新增中(mybatis 中 foreach 效率比较低)

如果希望批量新增,SQL 命令

1
2
insertintologVALUES
(default,1,2,3),(default,2,3,4),(default,3,4,5)

openSession()必须指定

  • 底层 JDBC 的 PreparedStatement.addBatch(); factory.openSession(ExecutorType.BATCH);

collectino=”” 要遍历的集合

item 迭代变量,#{迭代变量名}获取内容

open 循环后左侧添加的内容

close 循环后右侧添加的内容

separator 每次循环时,元素之间的分隔符

1
2
3
4
5
6
<select id="selIn" parameterType="list" resultType="log"> 
select * from log where id in
<foreach collection="list" item="abc" open="(" close=")" separator=",">
#{abc}
</foreach>
</select>

sql和include标签使用

某些 SQL 片段如果希望复用,可以使用<-sql>定义这个片段

1
2
3
<sql id="mysql"> 
id,accin,accout,money
</sql>

在<-select>或<-delete>或<-update>或<-insert>中使用<-include>引用

1
2
3
4
<select id=""> 
select <include refid="mysql"></include>
from log
</select>