【MyBatis】深入解析 MyBatis: foreach 标签属性及使用 foreach 标签实现动态 SQL 集合遍历操作(IN 子句、VALUES 子句的动态拼接、使用单元测试完成迭代构造)
·



MyBatis 动态 SQL
<foreach> 迭代集合
引入动态 SQL 集合遍历操作
我们平时可能会写出如下 SQL 语句:

上面这几条 SQL 都涉及到同时对多条数据进行操作;
但是在我们的 MyBatis 中要写出同等效果的 SQL ,就不能和上面写的 SQL 一样:

我们传参 id(#{id}) 是达不到 id(1,2,3,4) 的效果的;
如果我们传的是一个 String 类型的参数 “1, 2, 3, 4”,MyBatis 也不会把这个字符串一 一切割再解析;
所以我们要把这些连续的数据,比如 1, 2, 3, 4存入到一个 List 或者一个数组中,再依次从中读取元素,并且拼接到 SQL 语句中 ;

第一条 SQL 少了一个 in ,后文已更正;
通过上面的内容,我们已经明白 MyBatis 如何实现这些带有 (1,2,3,4) 这样式的 SQL,也就是通过拼接的思想,那么接下来,我们需要知道该怎么拼接;
<foreach> 标签的循环控制参数

对集合进行遍历时可以使用该标签。标签有如下属性:
| 属性名 | 说明 |
|---|---|
| collection | 绑定方法参数中的集合,如 List、Set、Map 或数组对象 |
| item | 遍历时的每一个对象 |
| open | 语句块开头的字符串 |
| close | 语句块结束的字符串 |
| separator | 每次遍历之间间隔的字符串 |
这个表格清晰地展示了 MyBatis 动态 SQL 中 <foreach> 标签的各个属性及其作用。
IN 子句动态拼接
比如这条 SQL
delete from user_info where id in (1,2,3,4);
重点需要拼接出 (1,2,3,4) 这块地方,我们的拼接应该从
List<Integer>- 前缀
"("- 后缀
")"- 单个元素
1 2 3 4- 元素和元素之间的分割符
逗号 ,- 去掉最后一个分割符
1,2,3,4,换成1,2,3,4
需求:根据多个userid,删除用户数据
接口方法:



<delete id="batchDelete">
DELETE FROM user_info
WHERE id IN
<foreach collection="ids" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</delete>
生成单元测试:


运行对应测试类方法,观察打印日志:

确认表对应记录是否更新数据:


集合参数的 VALUES 子句迭代构造
又比如这条 SQL
insert into user_info(username,`password`)
values("username1","p1"),("username2","p2"),("username3","p3");
我们需要拼接出("username1","p1"),("username2","p2"),("username3","p3") 这块地方
List<UserInfo>- 无前缀、后缀
- 单个元素
("username1","p1")(UserInfo.username, userInfo.password)- 元素和元素之间的分割符
逗号 ,- 去掉最后一个分割符
<insert id="batchinsert">
INSERT INTO user_info (username, password)
VALUES
<foreach collection="userInfos" item="userInfo" separator=",">
(#{userInfo.username}, #{userInfo.password})
</foreach>
</insert>


- Arrays.asList() 基本作用
- 将多个对象转换为一个 固定长度 的 List 集合(底层仍是数组)。
- 为什么需要 Arrays.asList()?
- 快速初始化集合:比手动
new ArrayList<>()更简洁。- 批量操作支持:适合需要传入 List 参数的场景(如 MyBatis 批量插入)。
- 节省内存:底层直接包装数组,无需额外分配内存。
特性 说明 固定大小 返回的 List 长度不可变(不能 add/remove,会抛UnsupportedOperationException)视图模式 对 List 的修改会同步到原始数组(反之亦然) 不支持基本类型 如 int[]需用包装类Integer[]

运行对应测试类方法,观察打印日志:

确认表对应记录是否更新数据:



更多推荐

所有评论(0)