if where标签
一个非常重要的功能
随着用户的输入或者是外部条件的变化而改变的SQL语句
我们称为SQL语句
只有传形参的有值 其他的属性都是null
所以并没有查询到数据
我们不难免会发现我们先前的
SQL的语句是固定死的
这样局限性太高
在xml映射文件中使用if标签可以实现动态SQL
SQL语句会根据传入参数的数量而变化
if标签用来做条件判断 这个条件要声明
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--复制引用-->
<mapper namespace="org.example.mybatis.mapper.UserMapper">
<!--动态语句-->
<select id="list" resultType="org.example.mybatis.pojo.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>
将SQL语句进行判断后填充
where标签 可以去除多余的and 和 where
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--复制引用-->
<mapper namespace="org.example.mybatis.mapper.UserMapper">
<!--动态语句-->
<select id="list" resultType="org.example.mybatis.pojo.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>
if 案例
更新三个字段
首先赋值指定内容的字段
接着删掉不需要修改的字段
启动更新
数据库表中的数据完成了更新
但是其余字段是null
根据id去更新时 我们写是写死的 每一次都要传递更新
传递就去更新字段 不传递字段值就是null
这样子的更新并不灵活 我们要将员工信息更细改为动态更新
动态更新员工 如果传递时有数值 就更新 没有传递值 就还是默认数值
在XML文件里映射并书写动态SQL语句
指定id 就
是映射的方法名 即SQL语句的标签 生成的update标签是根据书写的方法名自动识别的
动态映射
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--复制引用-->
<mapper namespace="org.example.mybatis.mapper.UserMapper">
<update id="update">
<!--动态更新SQL-->
update emp
set
<if test="username !=null ">username=#{username},</if>
<if test="password !=null ">password=#{password},</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="deptID !=null ">dept_id=#{deptID},</if>
<if test="entryDate !=null ">entrydate=#{entryDate},</if>
<if test="creatTime !=null ">create_time=#{creatTime},</if>
<if test="updateTime !=null ">update_time=#{updateTime}</if>
where id=#{id}
</update>
<!--动态语句-->
<select id="list" resultType="org.example.mybatis.pojo.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>
写在Mapper接口里的
package org.example.mybatis;
import org.example.mybatis.mapper.UserMapper;
import org.example.mybatis.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@SpringBootTest //springboot整合单元测试的注解
class MybatisApplicationTests {
@Autowired
//声明接口类型的对象 将此对象注入进来
private UserMapper userMapper;
@Test
public void testList() {
// List<User> userList = userMapper.list("张", (short) 1,
// LocalDate.of(2010, 1, 1),
// LocalDate.of(2020, 1, 1));
List<User> userList =userMapper.list("张",null,null,null);
System.out.println(userList);
}
@Test
//动态更新员工数据 更新ID为14的员工 更新Username name gender
public void testUpdata() {
User user = new User();
user.setId(13);
user.setUsername("Dduo1");
user.setName("多多");
user.setGender((short) 1);
user.setCreatTime(LocalDateTime.now());
user.setUpdateTime(LocalDateTime.now());
//执行新增员工信息的操作
userMapper.update(user);
}
}
数据库中ID为13的员工信息完成了更新
set标签
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--复制引用-->
<mapper namespace="org.example.mybatis.mapper.UserMapper">
<update id="update">
<!--动态更新SQL-->
update emp
<!--用来替换set关键字 可以更新所有的标签并去除逗号-->
<set>
<if test="username !=null ">username=#{username},</if>
<if test="password !=null ">password=#{password},</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="deptID !=null ">dept_id=#{deptID},</if>
<if test="entryDate !=null ">entrydate=#{entryDate},</if>
<if test="creatTime !=null ">create_time=#{creatTime},</if>
<if test="updateTime !=null ">update_time=#{updateTime}</if>
</set>
where id=#{id}
</update>
<!--动态语句-->
<select id="list" resultType="org.example.mybatis.pojo.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>
小结
foreach标签
循环遍历
动态SQL
xml文件里映射
在测试里面调用方法
传入形参集合
遍历集合
拿到集合里的每一个元素
然后拼接SQL语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--复制引用-->
<mapper namespace="org.example.mybatis.mapper.UserMapper">
<!--批量删除员工信息-->
<!--delete from emp where id in (2,3)-->
<delete id="deleteByIds">
<!--
collection 遍历的集合
item 遍历出来的集合
separator 分隔符
open 遍历开始前拼接的SQL片段
close 遍历结束后拼接的SQL片段
标签体内写要遍历的元素
-->
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
</mapper>
mapper接口
package org.example.mybatis.mapper;
import org.apache.ibatis.annotations.*;
import org.example.mybatis.pojo.User;
import java.time.LocalDate;
import java.util.List;
@Mapper//表示当前是Mybatis的一个接口 此时程序运行时框架会自动生成实现类对象(代理对象) 并交给spring的ioc容器
public interface UserMapper {
//批量删除员工
public void deleteByIds(List<Integer> ids);
}
测试类
package org.example.mybatis;
import org.example.mybatis.mapper.UserMapper;
import org.example.mybatis.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@SpringBootTest //springboot整合单元测试的注解
class MybatisApplicationTests {
@Autowired
//声明接口类型的对象 将此对象注入进来
private UserMapper userMapper;
@Test
//批量删除员工3 4 5
public void testDeleteByIds(){
List<Integer> ids= Arrays.asList(3,4,5);
userMapper.deleteByIds(ids);
}
}
小结
sql include标签
配套使用
看这个配置了两条SQL的映射文件
将代码抽取 抽取一部分SQL片段
然后需要SQL时再引入
sql标签负责抽取SQL
include负责引用片段
组件封装