目录
查询结果1:Emp emp = new Emp(null,"张三",20,"男");
查询结果2:Emp emp = new Emp(null,"",20,"男");
查询结果3:Emp emp = new Emp(null,"",null,"");
查询结果:Emp emp = new Emp(null,"张三",20,"男");
五、动态SQL之choose、when、otherwise标签
<choose> 标签
<when> 标签
<otherwise> 标签
<foreach> 标签的属性
一、动态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中的if
或else 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>
解析:
-
SQL结构:使用
in
关键字,删除满足emp_id
在指定列表中的记录。 -
<foreach>
标签:-
collection="empIds"
:指定要遍历的数组是empIds
。 -
item="empId"
:定义当前遍历的元素为empId
。 -
separator=","
:指定每次循环生成的内容之间用逗号,
分隔。
-
-
手动添加括号:在
<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代码
解析:
-
SQL结构:使用
in
关键字,删除满足emp_id
在指定列表中的记录。 -
<foreach>
标签:-
collection="empIds"
:指定要遍历的数组是empIds
。 -
item="empId"
:定义当前遍历的元素为empId
。 -
separator=","
:指定每次循环生成的内容之间用逗号,
分隔。
-
-
手动添加括号:在
<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代码
解析:
-
SQL结构:使用
or
关键字,删除满足emp_id
等于任意一个指定值的记录。 -
<foreach>
标签:-
separator="or"
:指定每次循环生成的内容之间用or
分隔。
-
-
动态生成条件:每次循环生成一个
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标签。