目录
什么是动态SQL
随着用户输入或外部条件变化而变化的SQL语句,就称为动态SQL
select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and entrydate between #{begin} and #{end} order by update_time desc
上面SQL语句如果使用中条件查询中实际上是有问题的 ,如果缺参,是查询不出为们想要的数据的,如果我们传入userList("张",null,null,null)查询出来是空的
而使用动态SQL就可以解决这个问题
动态SQL-if
<if>:用于判断条件是否成立,使用test属性进行条件判断,如果条件为true,则拼接SQL
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!-- resultType:单条记录所封装的类型-->
<select id="userList" resultType="com.itheima.bean.User">
select * from emp where
<if test="name != null">
name like concat('%',#{name},'%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between #{begin} and #{end}
</if>
order by update_time desc
</select>
</mapper>
测试
但是还是有问题,第一个参数为null的话,与编译SQL会有问题,而直接把第二参数and gender = ?拼接到where后面,也就是多了一个and,如果删掉and,想要加上第一个参数,又会少了一个and,同样会报语法错误
所以MyBatis提供了<where></where>标签,只要把sql到where替换掉,就可以自动去除多余的and或or
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!-- resultType:单条记录所封装的类型-->
<select id="userList" resultType="com.itheima.bean.User">
select * from emp
<where>
<if test="name != null">
name like concat('%',#{name},'%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between #{begin} and #{end}
</if>
</where>
order by update_time desc
</select>
</mapper>
同样的,在update的时候,Mybatis给我们提供了<set></set>标签用于替换set关键字,用于去掉多余的逗号
动态SQL-foreach
一般用于批量操作,比如批量删除,从前端返回一个删除列表,需要遍历列表删除数据
foreach有几个属性:
collection:遍历的集合
item:遍历出来的元素
separator:分割符
open:遍历开始前拼接的SQL片段
close:遍历结束后拼接的SQL片段
<delete id="deleteIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
mapper定义一个批量删除方法
public void deleteIds(List<Integer> ids);
测试
@Test
public void deleteByIds(){
List<Integer> ids = Arrays.asList(5,6,7);
empMapper.deleteIds(ids);
}
动态SQL-sql&include
<sql id=""></sql>标签用于封装sql片段,id表示唯一标识
<include refid=""></include>用于引用封装的sql片段,refid指向sql的id表示应用那个sql片段
在上面代码中,标出来的SQL是一样的,就可以使用sql标签将其封装起来