2025/2/23 1-DAY《尚硅谷》—— MyBatis 动态SQL(涵盖各种标签以及使用实例演示和解析)——if标签、where标签、trim标签、choose、when......

目录

一、动态SQL简介以及实例项目结构(附代码)

1、简介动态SQL简介

2、实例项目结构(附代码)

项目结构总览

DynamicSQLMapper.java代码

DynamicSQLMapper.xml代码

DynamicMapperTest.java代码

Emp.java代码

SqlSessionUtil. java代码

mybatis-config.xml代码

jdbc.properties代码

log4j.xml代码

二、动态SQL之if标签

1、使用实例演示

DynamicSQLMapper.java代码

DynamicSQLMapper.xml代码

DynamicMapperTest.java代码

查询结果:查询成功!

2、详细解析

三、动态SQL之where标签

1、使用实例演示

DynamicSQLMapper.xml代码

查询结果1:Emp emp = new Emp(null,"张三",20,"男");

查询结果2:Emp emp = new Emp(null,"",20,"男");

查询结果3:Emp emp = new Emp(null,"",null,"");

2、详细解析

四、动态SQL之trim标签

1、使用实例演示

DynamicSQLMapper.xml代码

查询结果:Emp emp = new Emp(null,"张三",20,"男");

2、详细解析 

五、动态SQL之choose、when、otherwise标签

1、使用实例演示

DynamicSQLMapper.java代码

DynamicSQLMapper.xml代码

DynamicMapperTest.java 代码

查询结果:查询成功!

2、详细解析 

<choose> 标签

<when> 标签

<otherwise> 标签

六、动态SQL之foreach标签(批量添加)

1、使用实例演示

DynamicSQLMapper.java代码

DynamicSQLMapper.xml代码

DynamicMapperTest.java 代码

查询结果:添加成功!

2、详细解析 

<foreach> 标签的属性

七、动态SQL之foreach标签(批量删除)

实例演示一——方法一

DynamicSQLMapper.xml代码

查询结果:删除成功!

 实例演示二——方法二

DynamicSQLMapper.xml代码

查询结果:修改测试为删除9,10,删除成功!

  实例演示三——方法三

 DynamicSQLMapper.xml代码

查询结果:修改测试为删除5,8,删除成功!

总结分析 

八、动态SQL之sql标签

 1、使用实例演示

DynamicSQLMapper.xml代码

DynamicMapperTest.java代码

查询结果:

2、详细解析 

1.   <sql>标签

2.   <include>标签

 九、心得体会


一、动态SQL简介以及实例项目结构(附代码)

1、简介动态SQL简介

        MyBatis框架的动态SQL技术是一种根据特定条件动态拼接SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题。

2、实例项目结构(附代码)

项目结构总览

// mybatis_dynamicSQL 项目结构

mybatis_dynamicSQL
├── .idea // 项目配置文件,包括IDE设置等
├── src // 源代码目录
│   ├── main // 主代码目录
│   │   ├── java // Java源代码
│   │   │   └── com.atguigu.mybais // 包路径
│   │   │       ├── mapper // MyBatis的Mapper接口
│   │   │       │   └── DynamicSQLMapper.java // DynamicSQL的Mapper接口
│   │   │       ├── pojo // 实体类
│   │   │       │   └── Emp.java // Emp实体类,包含属性、构造方法、getter和setter方法、toString方法
│   │   │       └── utils // 工具类
│   │   │           └── SqlSessionUtil.java // 用于获取SqlSession的工具类
│   │   └── resources // 资源文件目录
│   │       ├── com.atguigu.mybais.mapper // MyBatis的Mapper配置文件
│   │       │   └── DynamicSQLMapper.xml // DynamicSQL的Mapper配置文件
│   │       ├── jdbc.properties // 数据库连接配置文件
│   │       ├── log4j.xml // 日志配置文件
│   │       └── mybatis-config.xml // MyBatis配置文件
│   └── test // 测试代码目录
│       └── java
│           └── com.atguigu.mybais.test // 测试包路径
│               └── DynamicMapperTest.java // DynamicSQL的测试类
└── target // 构建输出目录
    └── pom.xml // Maven项目配置文件
DynamicSQLMapper.java代码
package com.atguigu.mybatis.mapper;

import com.atguigu.mybatis.pojo.Emp;

import java.util.List;

public interface DynamicSQLMapper {
    /* *
     *
     *根据条件查询员工信息
     * @param emp
     * @return java.util.List<com.atguigu.mybatis.pojo.Emp>
     * @author yzh
     * @create 2025/2/23
     **/
    List<Emp> getEmpByCondition(Emp emp);
}
DynamicSQLMapper.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.atguigu.mybatis.mapper.DynamicSQLMapper">

    <!--List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp where
        <if test = "empName != null and empName != ''">
            emp_name = #{empName}
        </if>
        <if test="age != null and age!= ''">
            and age = #{age}
        </if>
        <if test="gender != null and gender!= ''">
            and gender = #{gender}
        </if>
    </select>
</mapper>
DynamicMapperTest.java代码
package com.atguigu.mybatis.test;

import com.atguigu.mybatis.mapper.DynamicSQLMapper;
import com.atguigu.mybatis.pojo.Emp;
import com.atguigu.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;


public class DynamicMapperTest {

    @Test
    public void testGetEmpByCondition() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp = new Emp(null,"张三",20,"男");
        List<Emp> list = mapper.getEmpByCondition(emp);
        list.forEach(System.out::println);


    }


}

Emp.java代码

//实体类_有参构造、无参构造、getter和Setter方法、tostring方法

package com.atguigu.mybatis.pojo;


public class Emp {

    private Integer empId;

    private String empName;

    private Integer age;

    private String gender;

    public Emp(Integer empId, String empName, Integer age, String gender) {
        this.empId = empId;
        this.empName = empName;
        this.age = age;
        this.gender = gender;
    }


    public Emp() {
    }

    public Integer getEmpId() {
        return empId;
    }

    public void setEmpId(Integer empId) {
        this.empId = empId;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empId=" + empId +
                ", empName='" + empName + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

SqlSessionUtil. java代码

//工具类


package com.atguigu.mybatis.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class SqlSessionUtil {

    public static SqlSession getSqlSession() {
        SqlSession sqlSession = null;
        try {
            // 获取核心配置文件的输入流
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            // 获取SqlSessionFactoryBuilder对象
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            // 获取SqlSessionFactory对象
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
            // 获取sql的会话对象SqlSession,是MyBatis提供的操作数据库的对象;括号内的参数true可以决定是否自动提交
            //特别注意在此处若
            sqlSession = sqlSessionFactory.openSession(true);
            // 获取UserMapper的代理实现类对象
            // 调用mapper接口中的方法,实现添加用户信息的功能
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sqlSession;
    }

}

mybatis-config.xml代码

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//MyBatis.org//DTD Config 3.0//EN"
        "http://MyBatis.org/dtd/MyBatis-3-config.dtd">
<configuration>

    <properties resource="jdbc.properties"/>

    <settings>
        <!--将下划线映射为驼峰-->
        <setting name = "mapUnderscoreToCamelCase" value ="true"/>
        <!-- 开启延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 按需加载 -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

    <typeAliases>
        <package name="com.atguigu.mybatis.pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com.atguigu.mybatis.mapper"></package>
    </mappers>
</configuration>

jdbc.properties代码

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.100.191:3306/ssm?serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

log4j.xml代码

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug" />
    </logger>
<!--info信息-->
    <logger name="org.apache.ibatis">
        <level value="info" />
    </logger>
    <root>
<!--debug调试-->
        <level value="debug" />
        <appender-ref ref="STDOUT" />
    </root>
</log4j:configuration>

二、动态SQL之if标签

1、使用实例演示

DynamicSQLMapper.java代码
    /* *
     *
     *根据条件查询员工信息
     * @param emp
     * @return java.util.List<com.atguigu.mybatis.pojo.Emp>
     * @author yzh
     * @create 2025/2/23
     **/
    List<Emp> getEmpByCondition(Emp emp);
DynamicSQLMapper.xml代码
    <!--List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp where
        <if test = "empName != null and empName != ''">
            emp_name = #{empName}
        </if>
        <if test="age != null and age!= ''">
            and age = #{age}
        </if>
        <if test="gender != null and gender!= ''">
            and gender = #{gender}
        </if>
    </select>
DynamicMapperTest.java代码
    @Test
    public void testGetEmpByCondition() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp = new Emp(null,"张三",20,"男");
        List<Emp> list = mapper.getEmpByCondition(emp);
        list.forEach(System.out::println);


    }
查询结果:查询成功!
DEBUG 02-23 11:34:54,897 ==>  Preparing: select * from t_emp where emp_name = ? and age = ? and gender = ? (BaseJdbcLogger.java:137) 
DEBUG 02-23 11:34:54,930 ==> Parameters: 张三(String), 20(Integer), 男(String) (BaseJdbcLogger.java:137) 
DEBUG 02-23 11:34:54,952 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{empId=1, empName='张三', age=20, gender='男'}

进程已结束,退出代码为 0

2、详细解析

        select * from t_emp where
        <if test = "empName != null and empName != ''">
            emp_name = #{empName}
        </if>
        <if test="age != null and age!= ''">
            and age = #{age}
        </if>
        <if test="gender != null and gender!= ''">
            and gender = #{gender}
        </if>

        if标签可通过test属性的表达示进行判断,若表达式的结果为true,则标签中的内容会执行;反之标签中的内容不会执行。

注意: != 此符号中间不允许存在空格,否则会提示错误!

三、动态SQL之where标签

1、使用实例演示

仅修改DynamicSQLMapper.xml和DynamicMapperTest.java代码,其它代码不做修改。

DynamicSQLMapper.xml代码
    <!--List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp
        <where>
            <if test = "empName != null and empName != ''">
                emp_name = #{empName}
            </if>
            <if test="age != null and age!= ''">
                and age = #{age}
            </if>
            <if test="gender != null and gender!= ''">
                and gender = #{gender}
            </if>
        </where>
    </select>
查询结果1:Emp emp = new Emp(null,"张三",20,"男");
DEBUG 02-23 12:23:45,762 ==>  Preparing: select * from t_emp WHERE emp_name = ? and age = ? and gender = ? (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:23:45,796 ==> Parameters: 张三(String), 20(Integer), 男(String) (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:23:45,820 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{empId=1, empName='张三', age=20, gender='男'}
查询结果2:Emp emp = new Emp(null,"",20,"男");
DEBUG 02-23 12:25:32,090 ==>  Preparing: select * from t_emp WHERE age = ? and gender = ? (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:25:32,129 ==> Parameters: 20(Integer), 男(String) (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:25:32,151 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{empId=1, empName='张三', age=20, gender='男'}

进程已结束,退出代码为 0
查询结果3:Emp emp = new Emp(null,"",null,"");
DEBUG 02-23 12:29:23,976 ==>  Preparing: select * from t_emp (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:29:24,006 ==> Parameters:  (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:29:24,027 <==      Total: 4 (BaseJdbcLogger.java:137) 
Emp{empId=1, empName='张三', age=20, gender='男'}
Emp{empId=2, empName='李四', age=22, gender='男'}
Emp{empId=3, empName='王五', age=23, gender='男'}
Emp{empId=4, empName='赵六', age=24, gender='男'}

进程已结束,退出代码为 0

2、详细解析

        select * from t_emp
        <where>
            <if test = "empName != null and empName != ''">
                emp_name = #{empName}
            </if>
            <if test="age != null and age!= ''">
                and age = #{age}
            </if>
            <if test="gender != null and gender!= ''">
                and gender = #{gender}
            </if>
        </where>

        查询结果1——若where标签中有条件成立,会自动在select * from t_emp后生成where关键字
        查询结果2——where标签会自动将内容前多余的and去掉
        查询结果3——若where标签中没有任何一个条件成立,则where没有任何功能

注意:where标签不能去掉条件最后多余的and。

四、动态SQL之trim标签

1、使用实例演示

仅修改DynamicSQLMapper.xml和DynamicMapperTest.java代码,其它代码不做修改。

DynamicSQLMapper.xml代码
    <!--List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select * from t_emp
        <trim prefix="where" suffixOverrides="and">
            <if test="empName != null and empName != ''">
                emp_name = #{empName} and
            </if>
            <if test="age != null and age != ''">
                age = #{age} and
            </if>
            <if test="gender != null and gender != ''">
                gender = #{gender}
            </if>
        </trim>
    </select>
查询结果:Emp emp = new Emp(null,"张三",20,"男");
DEBUG 02-23 12:45:39,676 ==>  Preparing: select * from t_emp where emp_name = ? and age = ? and gender = ? (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:45:39,711 ==> Parameters: 张三(String), 20(Integer), 男(String) (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:45:39,744 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{empId=1, empName='张三', age=20, gender='男'}

进程已结束,退出代码为 0

2、详细解析 

        <trim prefix="where" suffixOverrides="and">
            <if test="empName != null and empName != ''">
                emp_name = #{empName} and
            </if>
            <if test="age != null and age != ''">
                age = #{age} and
            </if>
            <if test="gender != null and gender != ''">
                gender = #{gender}
            </if>
        </trim>

  • prefix、suffix:在标签中内容前面或后面添加指定内容
  • prefixOverrides、suffixOverrides:在标签中内容前面或后面去掉指定内容

五、动态SQL之choose、when、otherwise标签

1、使用实例演示

仅修改DynamicSQLMapper.xml和DynamicMapperTest.java代码,其它代码不做修改。

DynamicSQLMapper.java代码
    /* *
     * 
     *使用choose查询员工信息
     * @param emp
     * @return java.util.List<com.atguigu.mybatis.pojo.Emp>
     * @author yzh
     * @create 2025/2/23
     **/
    List<Emp> getEmpByChoose(Emp emp);
DynamicSQLMapper.xml代码
    <!--List<Emp> getEmpByChoose(Emp emp);-->
    <select id="getEmpByChoose" resultType="Emp">
        select * from t_emp
        <where>
            <choose>
                <when test="empName != null and empName != ''">
                    emp_name = #{empName}
                </when>
                <when test="age != null and age != ''">
                    age = #{age}
                </when>
                <when test="gender != null and gender != ''">
                    gender = #{gender}
                </when>
            </choose>
        </where>
    </select>
DynamicMapperTest.java 代码
    @Test
    public void testGetEmpByChoose() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp = new Emp(null,"张三",20,"男");
        List<Emp> list = mapper.getEmpByChoose(emp);
        list.forEach(System.out::println);
    }
查询结果:查询成功!
DEBUG 02-23 12:58:03,339 ==>  Preparing: select * from t_emp WHERE emp_name = ? (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:58:03,372 ==> Parameters: 张三(String) (BaseJdbcLogger.java:137) 
DEBUG 02-23 12:58:03,395 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{empId=1, empName='张三', age=20, gender='男'}

进程已结束,退出代码为 0

2、详细解析 

        select * from t_emp
        <where>
            <choose>
                <when test="empName != null and empName != ''">
                    emp_name = #{empName}
                </when>
                <when test="age != null and age != ''">
                    age = #{age}
                </when>
                <when test="gender != null and gender != ''">
                    gender = #{gender}
                </when>
            </choose>

        </where>

在MyBatis中,<choose><when><otherwise>标签用于实现类似于Java中的if...else if...else逻辑。它们允许我们在SQL语句中根据不同的条件动态生成不同的查询条件。

<choose>标签

<choose>标签类似于Java中的switch语句,它包含多个<when>子标签和一个可选的<otherwise>子标签。<choose>标签会根据条件的顺序依次判断每个<when>标签中的条件,如果某个条件成立,则生成对应的SQL片段。如果所有<when>标签的条件都不成立,则会执行<otherwise>标签中的内容(如果有的话)。

<when>标签

<when>标签用于定义条件判断,类似于Java中的ifelse if。每个<when>标签都有一个test属性,该属性的值是一个OGNL表达式,用于判断条件是否成立。如果条件成立,则生成对应的SQL片段。

<otherwise>标签

<otherwise>标签是可选的,类似于Java中的else。如果所有<when>标签的条件都不成立,则会执行<otherwise>标签中的内容。

六、动态SQL之foreach标签(批量添加)

1、使用实例演示

DynamicSQLMapper.java代码

接口设计

  • 方法名insertMoreEmp

  • 参数:接收一个List<Emp>类型的参数,表示多个员工信息。

  • 返回值:无返回值(void),因为这是一个插入操作。

  • 注解:使用@Param注解指定参数名称,方便在XML映射文件中引用。

    /* *
     *
     *批量添加员工信息
     * @param emps
     * @return void
     * @author yzh
     * @create 2025/2/23
     **/
    void insertMoreEmp(@Param("emps") List<Emp> emps);
DynamicSQLMapper.xml代码

SQL设计

  • SQL语句insert into t_emp values (null, ?, ?, ?, null)

  • 动态部分:使用<foreach>标签遍历emps集合,生成多个插入值。

    <!--void insertMoreEmp(List<Emp> emps);-->
    <insert id="insertMoreEmp">
        insert into t_emp values
        <foreach collection="emps" item="emp" separator=",">
            (null,#{emp.empName},#{emp.age},#{emp.gender},null)
        </foreach>
    </insert>
DynamicMapperTest.java 代码
    @Test
    public void testInsertMoreEmp() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp1 = new Emp(null, "小明1", 20, "男");
        Emp emp2 = new Emp(null, "小明2", 20, "男");
        Emp emp3 = new Emp(null, "小明3", 20, "男");
        List<Emp> list = Arrays.asList(emp1, emp2, emp3);
        mapper.insertMoreEmp(list);
    }
查询结果:添加成功!
DEBUG 02-23 13:17:49,256 ==>  Preparing: insert into t_emp values (null,?,?,?,null) , (null,?,?,?,null) , (null,?,?,?,null) (BaseJdbcLogger.java:137) 
DEBUG 02-23 13:17:49,292 ==> Parameters: 小明1(String), 20(Integer), 男(String), 小明2(String), 20(Integer), 男(String), 小明3(String), 20(Integer), 男(String) (BaseJdbcLogger.java:137) 
DEBUG 02-23 13:17:49,318 <==    Updates: 3 (BaseJdbcLogger.java:137) 

进程已结束,退出代码为 0

2、详细解析 

    <!--void insertMoreEmp(List<Emp> emps);-->
    <insert id="insertMoreEmp">
        insert into t_emp values
        <foreach collection="emps" item="emp" separator=",">
            (null,#{emp.empName},#{emp.age},#{emp.gender},null)
        </foreach>

    </insert>

<foreach>标签的属性
  • collection:指定要遍历的集合或数组。这个属性的值通常是一个List、Set、数组或Map的键集合。

  • item:定义一个变量名,表示集合或数组中的每一个元素。在循环体内,可以通过#{item}来引用当前元素。

  • separator:指定每次循环生成的内容之间的分隔符。例如,在批量插入时,可以使用逗号,分隔多个插入值。

七、动态SQL之foreach标签(批量删除)

DynamicSQLMapper.java代码

接口设计

  • 方法名deleteMoreEmp

  • 参数:接收一个Integer[]类型的参数,表示多个员工ID。

  • 返回值:无返回值(void),因为这是一个删除操作。

  • 注解:使用@Param注解指定参数名称,方便在XML映射文件中引用。

    /* *
     *
     *批量删除员工信息
     * @param empIds
     * @return void
     * @author yzh
     * @create 2025/2/23
     **/
    void deleteMoreEmp(@Param("empIds") Integer[] empIds);

DynamicMapperTest.java 代码 

    @Test
    public void testDeleteMoreEmp() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Integer[] empIds = new Integer[]{6, 7};
        mapper.deleteMoreEmp(empIds);
    }

实例演示一——方法一

DynamicSQLMapper.xml代码
    <!--void deleteMoreEmp(@Param("empIds") Integer[] empIds); -->
    <delete id="deleteMoreEmp">
        delete from t_emp where emp_id in
        (
        <foreach collection="empIds" item="empId" separator=",">
            #{empId}
        </foreach>
        )
    </delete>

解析:

  1. SQL结构:使用in关键字,删除满足emp_id在指定列表中的记录。

  2. <foreach>标签

    • collection="empIds":指定要遍历的数组是empIds

    • item="empId":定义当前遍历的元素为empId

    • separator=",":指定每次循环生成的内容之间用逗号,分隔。

  3. 手动添加括号:在<foreach>标签外部手动添加(),确保SQL语法正确。

查询结果:删除成功!
DEBUG 02-23 13:37:54,683 ==>  Preparing: delete from t_emp where emp_id in ( ? , ? ) (BaseJdbcLogger.java:137) 
DEBUG 02-23 13:37:54,716 ==> Parameters: 6(Integer), 7(Integer) (BaseJdbcLogger.java:137) 
DEBUG 02-23 13:37:54,733 <==    Updates: 2 (BaseJdbcLogger.java:137) 

进程已结束,退出代码为 0

 实例演示二——方法二

DynamicSQLMapper.xml代码

解析:

  1. SQL结构:使用in关键字,删除满足emp_id在指定列表中的记录。

  2. <foreach>标签

    • collection="empIds":指定要遍历的数组是empIds

    • item="empId":定义当前遍历的元素为empId

    • separator=",":指定每次循环生成的内容之间用逗号,分隔。

  3. 手动添加括号:在<foreach>标签外部手动添加(),确保SQL语法正确。

<delete id="deleteMoreEmp">
    delete from t_emp where emp_id in
    <foreach collection="empIds" item="empId" separator="," open="(" close=")">
        #{empId}
    </foreach>
</delete>
查询结果:修改测试为删除9,10,删除成功!
DEBUG 02-23 13:41:30,079 ==>  Preparing: delete from t_emp where emp_id in ( ? , ? ) (BaseJdbcLogger.java:137) 
DEBUG 02-23 13:41:30,110 ==> Parameters: 9(Integer), 10(Integer) (BaseJdbcLogger.java:137) 
DEBUG 02-23 13:41:30,112 <==    Updates: 2 (BaseJdbcLogger.java:137) 

进程已结束,退出代码为 0

  实例演示三——方法三

 DynamicSQLMapper.xml代码

解析:

  1. SQL结构:使用or关键字,删除满足emp_id等于任意一个指定值的记录。

  2. <foreach>标签

    • separator="or":指定每次循环生成的内容之间用or分隔。

  3. 动态生成条件:每次循环生成一个emp_id = #{empId}的条件。

    <!--void deleteMoreEmp(@Param("empIds") Integer[] empIds); -->
    <delete id="deleteMoreEmp">
        delete from t_emp where
        <foreach collection="empIds" item="empId" separator="or">
            emp_id = #{empId}
        </foreach>
    </delete>
查询结果:修改测试为删除5,8,删除成功!
DEBUG 02-23 13:46:17,176 ==>  Preparing: delete from t_emp where emp_id = ? or emp_id = ? (BaseJdbcLogger.java:137) 
DEBUG 02-23 13:46:17,206 ==> Parameters: 5(Integer), 8(Integer) (BaseJdbcLogger.java:137) 
DEBUG 02-23 13:46:17,208 <==    Updates: 2 (BaseJdbcLogger.java:137) 

进程已结束,退出代码为 0

总结分析 

foreach标签核心属性总结

属性 作用 示例值
collection 指定要遍历的集合或数组 emps
item 定义当前遍历的元素变量名 emp
separator 设置每次循环内容之间的分隔符 , 或 or
open 循环生成的 SQL 片段的前缀 (
close 循环生成的 SQL 片段的后缀 )

八、动态SQL之sql标签

 1、使用实例演示

仅修改DynamicSQLMapper.xml文件其它代码不做修改。

DynamicSQLMapper.xml代码
    <sql id="empColumns">
        emp_id, emp_name, age, gender, dept_id
    </sql>

    <!--List<Emp> getEmpByCondition(Emp emp);-->
    <select id="getEmpByCondition" resultType="Emp">
        select <include refid="empColumns"></include> from t_emp
        <trim prefix="where" suffixOverrides="and">
            <if test="empName != null and empName != ''">
                emp_name = #{empName} and
            </if>
            <if test="age != null and age != ''">
                age = #{age} and
            </if>
            <if test="gender != null and gender != ''">
                gender = #{gender}
            </if>
        </trim>
    </select>
DynamicMapperTest.java代码
    @Test
    public void testGetEmpByCondition() {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        Emp emp = new Emp(null,"张三",20,"男");
        List<Emp> list = mapper.getEmpByCondition(emp);
        list.forEach(System.out::println);
    }
查询结果:
DEBUG 02-23 14:04:00,512 ==>  Preparing: select emp_id, emp_name, age, gender, dept_id from t_emp where emp_name = ? and age = ? and gender = ? (BaseJdbcLogger.java:137) 
DEBUG 02-23 14:04:00,555 ==> Parameters: 张三(String), 20(Integer), 男(String) (BaseJdbcLogger.java:137) 
DEBUG 02-23 14:04:00,591 <==      Total: 1 (BaseJdbcLogger.java:137) 
Emp{empId=1, empName='张三', age=20, gender='男'}

进程已结束,退出代码为 0

2、详细解析 

在 MyBatis 中,<sql> 标签用于定义可重用的 SQL 片段,而 <include> 标签用于引用这些片段。通过这种方式,可以避免重复编写相同的 SQL 代码,提高代码的可维护性和可读性。


1. <sql> 标签
  • 作用:定义一个可重用的 SQL 片段。

  • 属性

    • id:指定 SQL 片段的唯一标识符,用于在其他地方引用。

  • 示例

<sql id="empColumns">
    emp_id, emp_name, age, gender, dept_id
</sql>

2. <include> 标签
  • 作用:引用通过 <sql> 标签定义的 SQL 片段。

  • 属性

    • refid:指定要引用的 SQL 片段的 id

  • 示例

<select id="getEmpByCondition" resultType="Emp">
    select <include refid="empColumns"></include> from t_emp
</select>

 九、心得体会

        终于肝完了,18000字左右,2025/2/23周日 -10:25-14:13:37,历史四小时结束,洗澡休息约会去喽!

2025/2/23 1-DAY《尚硅谷》—— MyBatis 动态SQL(涵盖各种标签以及使用实例演示和解析)——if标签、where标签、trim标签、choose、when、otherwise标签、foreach标签、sql标签。