# Mybatis动态SQL
一、if标签

这个SQL语句固定死了,假如我们只输入张,后面几个都是空,是查不出结果的,所以是有问题的,我们希望在任意一个输入框输出内容,其他的输入框不输入,就都能查出来。
empMapper.xml

<?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">
<!-- id于mapper接口中的方法名一致
resultType是单条记录封装的类型-->
<select id="select" resultType="com.itheima.pojo.Emp">
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>
测试
1、
// 动态SQL
List<Emp> empList = empMapper.select("张", null, null, null);
System.out.println(empList);
2、
List<Emp> empList = empMapper.select(null, (short)1, null, null);
System.out.println(empList);
报错
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'and gender = 1

找到and gender,因为

因为name为null,所以直接执行第二个if,不为空,就带上了and,sql语法错误。
mybatis提供了where标签
-- where标签作用:1、判断所有标签是否成立,不成立就不生成where
-- 2、去掉标签中的and
<?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">
<!-- id于mapper接口中的方法名一致
resultType是单条记录封装的类型-->
<select id="select" resultType="com.itheima.pojo.Emp">
select *
from emp
-- where标签作用:1、判断所有标签是否成立,不成立就不生成where
-- 2、去掉标签中的and
<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
</where>
</select>
</mapper>


二、if案例

//固定写死的更新
@Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image},job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime}" +
" where id=#{id}")
public void update(Emp emp);

没有image,job,entrdate,这样更新之后,这些字段为null

当我们使用了动态SQL
首先在empMapper接口中新添加一个方法update2
public void update2(Emp emp);
其次在EmpMapper.xml中添加
<update id="update2">
update emp
<set>
<if test="username!=null">
username=#{username},
</if>
<if test="name!=null">
name=#{name},
</if>
<if test="gender!=null">
gender=#{gender},
</if>
<if test="image!=null">
image=#{image},
</if>
<if test="job!=null">
job=#{job},
</if>
<if test="entrydate!=null">
entrydate=#{entrydate},
</if>
<if test="deptId!=null">
dept_id=#{deptId},
</if>
<if test="updateTime!=null">
update_time=#{updateTime}
</if>
</set>
where id = #{id}
</update>
最后进行测试
//动态更新
@Test
public void update2(){
// 创建Emp对象
Emp emp = new Emp();
emp.setId(21);
emp.setUsername("Tom555");
emp.setName("汤姆555");
emp.setGender((short)2);
emp.setUpdateTime(LocalDateTime.now());
empMapper.update2(emp);
}

可以看到其余的信息都在。

小结

三、foreach标签
批量删除,首先先写SQL语句

其次,在EmpMapper接口中声明一个方法
// 批量删除
public void deleteByIds(List<Integer> ids);
在EmpMapper.xml中书写SQL语句
<!-- 批量删除(18,19,20)-->
<!-- collection:集合名称
item:遍历出来的元素/项
separator:分隔符是什么
open:遍历开始前拼接的片段
close:遍历结束后拼接的片段
-->
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>

最后测试
// 删除多条员工信息
@Test
public void deleteByIds(){
List<Integer> list = Arrays.asList(16,21);
empMapper.deleteByIds(list);
}
结果:

四、sql&include标签
代码复用性比较差,因为有许多重复的,在后期维护的时候需要都修改,在Java中是用封装的办法提高代码的复用性


将这段代码抽取

引用

小结

一、if标签

这个SQL语句固定死了,假如我们只输入张,后面几个都是空,是查不出结果的,所以是有问题的,我们希望在任意一个输入框输出内容,其他的输入框不输入,就都能查出来。
empMapper.xml

<?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">
<!-- id于mapper接口中的方法名一致
resultType是单条记录封装的类型-->
<select id="select" resultType="com.itheima.pojo.Emp">
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>
测试
1、
// 动态SQL
List<Emp> empList = empMapper.select("张", null, null, null);
System.out.println(empList);
2、
List<Emp> empList = empMapper.select(null, (short)1, null, null);
System.out.println(empList);
报错
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'and gender = 1

找到and gender,因为

因为name为null,所以直接执行第二个if,不为空,就带上了and,sql语法错误。
mybatis提供了where标签
-- where标签作用:1、判断所有标签是否成立,不成立就不生成where
-- 2、去掉标签中的and
<?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">
<!-- id于mapper接口中的方法名一致
resultType是单条记录封装的类型-->
<select id="select" resultType="com.itheima.pojo.Emp">
select *
from emp
-- where标签作用:1、判断所有标签是否成立,不成立就不生成where
-- 2、去掉标签中的and
<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
</where>
</select>
</mapper>


二、if案例

//固定写死的更新
@Update("update emp set username=#{username},name=#{name},gender=#{gender},image=#{image},job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime}" +
" where id=#{id}")
public void update(Emp emp);

没有image,job,entrdate,这样更新之后,这些字段为null

当我们使用了动态SQL
首先在empMapper接口中新添加一个方法update2
public void update2(Emp emp);
其次在EmpMapper.xml中添加
<update id="update2">
update emp
<set>
<if test="username!=null">
username=#{username},
</if>
<if test="name!=null">
name=#{name},
</if>
<if test="gender!=null">
gender=#{gender},
</if>
<if test="image!=null">
image=#{image},
</if>
<if test="job!=null">
job=#{job},
</if>
<if test="entrydate!=null">
entrydate=#{entrydate},
</if>
<if test="deptId!=null">
dept_id=#{deptId},
</if>
<if test="updateTime!=null">
update_time=#{updateTime}
</if>
</set>
where id = #{id}
</update>
最后进行测试
//动态更新
@Test
public void update2(){
// 创建Emp对象
Emp emp = new Emp();
emp.setId(21);
emp.setUsername("Tom555");
emp.setName("汤姆555");
emp.setGender((short)2);
emp.setUpdateTime(LocalDateTime.now());
empMapper.update2(emp);
}

可以看到其余的信息都在。

小结

三、foreach标签
批量删除,首先先写SQL语句

其次,在EmpMapper接口中声明一个方法
// 批量删除
public void deleteByIds(List<Integer> ids);
在EmpMapper.xml中书写SQL语句
<!-- 批量删除(18,19,20)-->
<!-- collection:集合名称
item:遍历出来的元素/项
separator:分隔符是什么
open:遍历开始前拼接的片段
close:遍历结束后拼接的片段
-->
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>

最后测试
// 删除多条员工信息
@Test
public void deleteByIds(){
List<Integer> list = Arrays.asList(16,21);
empMapper.deleteByIds(list);
}
结果:

四、sql&include标签
代码复用性比较差,因为有许多重复的,在后期维护的时候需要都修改,在Java中是用封装的办法提高代码的复用性


将这段代码抽取

引用

小结
