MyBatis的foreach标签用于高效批量操作,支持IN查询和批量插入,需正确配置collection、open/close、separator,并配合if判空防止SQL错误。
` 怎么高效处理批量插入与 in 查询">
MyBatis 的 foreach 标签是处理批量操作最常用也最实用的动态 SQL 工具,核心在于用一次 SQL 语句完成多条数据的操作,避免循环单条执行带来的性能损耗和事务开销。
IN 查询:用 foreach 构建安全、合法的 WHERE 条件
当需要根据一组 ID 查用户、订单或商品时,直接拼接字符串易出错且有 SQL 注入风险。用 foreach 可自动包裹括号、逗号分隔,并由 MyBatis 绑定参数防止注入。
-
collection 值要匹配传参名:若方法参数是
@Param("ids") List<Long> ids,XML 中写collection="ids";若只传一个 List 且没加@Param,默认用collection="list" -
open 和 close 必须成对出现:比如
open="("+close=")",否则生成的 SQL 语法错误(如WHERE id IN 1,2,3不合法) -
separator 要选对符号:IN 子句用英文逗号,多个 OR 条件可考虑用
OR
示例:
<select id="selectUsersByIds" resultType="User">SELECT * FROM users WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
批量插入:一条 INSERT 语句写入多行数据
MySQL、PostgreSQL 等主流数据库支持 INSERT INTO t(col1,col2) VALUES (v1,v2),(v3,v4),... 语法。foreach 正是用来生成这种多值列表的。
立即学习“Java免费学习笔记(深入)”;
-
item 是每个对象的别名:比如传入
List<User>,就写item="user",然后用#{user.name}引用字段 -
separator 设为英文逗号:让每组
(...)之间用逗号连接 -
不要漏掉括号和空格:VALUES 后面直接跟 foreach,里面每个
#{...}都包在一对圆括号里
示例:
<insert id="batchInsertUsers">INSERT INTO users(name, email) VALUES
<foreach collection="users" item="user" separator=",">
(#{user.name}, #{user.email})
</foreach>
</insert>
数组与 Map 类型的 collection 写法要准确
MyBatis 对不同参数类型要求不同的 collection 值,写错会导致空集合或报错:
- 传
Long[] ids数组 →collection="array" - 传
List<String>且加了@Param("tags")→collection="tags" - 传
Map<String, Object>,想遍历 value →collection="map.values";遍历 key →collection="map.keys"
必须配合判空,避免空集合导致 SQL 错误
如果传入的集合为空,foreach 会生成空内容,比如 WHERE id IN ,直接报错。务必在外层加 if 判断:
SELECT * FROM users
<if test="ids != null and !ids.isEmpty()">
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
</select>


















