MyBatis中foreach集合用法详解
在 MyBatis 中,<foreach>
标签用于遍历集合(Collection、List、Array、Map),常用于构建动态 SQL 语句(如 IN
查询、批量插入等)。以下是详细用法和示例:
核心属性
属性 | 描述 |
---|---|
collection | 必填:传入的集合参数名(或默认别名 list/array ) |
item | 必填:遍历时元素的别名 |
index | 遍历的索引(List/Array 时为序号,Map 时为 key) |
open | 循环开始时的字符串(如 ( ) |
close | 循环结束时的字符串(如 ) ) |
separator | 元素间的分隔符(如 , ) |
一、遍历 List/Array 的 4 种场景
1. 直接传入 List(默认别名 list
)
xml
复制
下载
运行
<select id="selectByIds" resultType="User">SELECT * FROM userWHERE id IN<foreach collection="list" item="id" open="(" separator="," close=")">#{id}</foreach> </select>
java
复制
下载
List<User> selectByIds(List<Long> ids); // 调用时传入 List
2. 使用 @Param
指定集合名
xml
复制
下载
运行
<foreach collection="ids" item="id" ...> <!-- 使用自定义名称 -->
java
复制
下载
List<User> selectByIds(@Param("ids") List<Long> ids); // 指定参数名为 ids
3. 遍历 Array(默认别名 array
)
xml
复制
下载
运行
<foreach collection="array" item="item" ...>
java
复制
下载
List<User> selectByIdArray(Long[] idArray);
4. 遍历对象中的集合属性
java
复制
下载
public class QueryDTO {private List<Long> userIds;// getter/setter }
xml
复制
下载
运行
<foreach collection="userIds" item="id" ...> <!-- 直接使用属性名 -->
java
复制
下载
List<User> selectByDTO(QueryDTO dto);
二、遍历 Map 示例
xml
复制
下载
运行
<insert id="insertUsers">INSERT INTO user (name, age) VALUES<foreach collection="map" item="value" index="key" separator=",">(#{key}, #{value}) <!-- key=用户名, value=年龄 --></foreach> </insert>
java
复制
下载
void insertUsers(@Param("map") Map<String, Integer> userMap); // key:name, value:age
三、批量插入(常用)
xml
复制
下载
运行
<insert id="batchInsert">INSERT INTO user (name, email) VALUES<foreach collection="users" item="user" separator=",">(#{user.name}, #{user.email})</foreach> </insert>
java
复制
下载
int batchInsert(@Param("users") List<User> users);
⚠️ 注意事项
-
集合为 null 时的处理:
若传入的集合为null
,<foreach>
会报错。建议在 Java 代码中做空集合检查。 -
性能优化:
批量操作时,避免单次拼接过多 SQL(如超过 1000 条)。可分批执行:java
复制
下载
for (int i = 0; i < users.size(); i += 200) {mapper.batchInsert(users.subList(i, Math.min(i + 200, users.size()))); }
-
数据库方言差异:
部分数据库(如 Oracle)批量插入语法不同,需调整 SQL 结构:xml
复制
下载
运行
<!-- Oracle 批量插入示例 --> INSERT ALL <foreach collection="users" item="user">INTO user (name, email) VALUES (#{user.name}, #{user.email}) </foreach> SELECT 1 FROM DUAL
完整示例:动态更新多个字段
xml
复制
下载
运行
<update id="updateUser">UPDATE user<set><foreach collection="updateMap" item="value" index="key" separator=","><if test="value != null">${key} = #{value} <!-- 注意:字段名用 ${} 防注入需确保安全 --></if></foreach></set>WHERE id = #{userId} </update>
java
复制
下载
void updateUser(@Param("userId") Long id,@Param("updateMap") Map<String, Object> fields // key=字段名, value=新值 );
通过灵活使用 <foreach>
,可以高效处理集合型参数,简化动态 SQL 的编写。