动态sql概述
- 动态SQL是MyBatis强大特性之一。极大的简化我们拼装SQL的操作。
- 动态SQL 元素和使用JSTL 或其他类似基于XML 的文本处理器相似。
- MyBatis 采用功能强大的基于OGNL 的表达式来简化操作。
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
if判断
<select id="getEmpByConditionIf" resultType="com.mybatis.bean.Employee2">
select * from tbl_employee
<where>
<if test="gender!=null && gender==0">
and gender=0
</if>
<if test="deptId!=null">
and dept_id=#{deptId}
</if>
</where>
</select>
test中的为OGNL表达式,参数为Dao接口方法的参数
1. 值只能为索引0,1...或param1,param2...
2. 也可以在Dao接口方法的参数列表中通过注解@Param("name") +形参,来指定自定义的名字
3. 如果需要在test中加特殊符号,如&&,"",<,>等,需要使用对应的转义字符&&,"",<,>
其中&&和and等价,""和' '等价
4. ognl会进行字符串和数字的转换判断"0"==0
避免由于条件不符合导致的sql语句不合法
- where 1=1可以让where前缀一直存在
- 使用where标签包裹条件判断语句,可以自动添加where关键字,同时会将多余的and去除。
但where标签只会去掉符合条件的sql语句的第一个and, 如:and gender=0;
如果sql语句后面有and,不会去除,如: gender=0 and;
所以一般将and写在sql语句前面
trim标签(使用较少)
<select id="getEmpByConditionIf" resultType="com.mybatis.bean.Employee2">
select * from tbl_employee
<trim prefix="where" suffixOverrides="and">
<if test="gender!=null && gender==0">
gender=0 and
</if>
<if test="deptId!=null">
dept_id=#{deptId} and
</if>
</trim>
</select>
1. prefix:if条件判断的前缀,一般为where
2. prefixOverrides:前缀覆盖,将多余的前缀去除,如果if判断语句中没有多余的前缀,可以不用加该参数
3. suffix:后缀
4. sufferOverrides:后缀覆盖,将多余的后缀去除,针对where标签无法去除sql后面的and这种情况
choose分支选择
只选择其中一个符合的when作为条件,即只能有一个条件
<select id="getEmpByConditionIf" resultType="com.mybatis.bean.Employee2">
select * from tbl_employee
<where>
<choose >
<when test="gender==0">
gender=0
</when>
<when test="deptId!=null">
and dept_id=#{deptId}
</when>
<otherwise>
and id=1
</otherwise>
</choose>
</where>
set与if结合
where封装查询条件,set封装更新条件
set标签可以自动添加set关键字,去除多余的逗号
<update id="updateEmpByConditionSet">
update tbl_employee
<set>
<if test="lastName!=null">
last_name=#{lastName},
</if>
<if test="email!=null">
email=#{email},
</if>
<if test="gender!=null">
gender=#{gender}
</if>
</set>
where id=#{id}
</update>
同where,也可以使用trim标签替换set
最后测试时一定要提交
foreach循环
- 批量查询
- 批量保存
<select id="getEmpByConditionIf" resultType="com.mybatis.bean.Employee2">
select * from tbl_employee where id in
<!--
collection:传入的参数名,通过param1或注解@Param来指定
item:集合中的元素名,任意起名
separator:让集合中的元素以什么符号分割
open:以什么开始循环语句
close:以什么结束循环语句
index:索引,遍历集合时index代表索引号,item表示值;遍历map时index表示map的key,item表示map的值
-->
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</select>
<update id="updateEmpByConditionSet">
update tbl_employee
<set>
<if test="lastName!=null">
last_name=#{lastName},
</if>
<if test="email!=null">
email=#{email},
</if>
<if test="gender!=null">
gender=#{gender}
</if>
</set>
where id=#{id}
</update>
test内置的两个参数
补充
bind标签
可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值
sql标签
抽取可重用的sql片段,方便后面引用
- sql抽取经常要查询的列名,或者插入用的列名抽取出来方便引用
- include来引用已经抽取的sql
- include还可以自定义property,sql标签内部就能使用自定义的属性
- include取值的方式:${prop}