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 user
    WHERE 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);

⚠️ 注意事项

  1. 集合为 null 时的处理

    若传入的集合为 null<foreach> 会报错。建议在 Java 代码中做空集合检查。

  2. 性能优化

    批量操作时,避免单次拼接过多 SQL(如超过 1000 条)。可分批执行:

    java

    复制

    下载

    复制代码
    for (int i = 0; i < users.size(); i += 200) {
        mapper.batchInsert(users.subList(i, Math.min(i + 200, users.size())));
    }
  3. 数据库方言差异

    部分数据库(如 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 的编写。

相关推荐
while(1){yan}15 小时前
MyBatis Generator
数据库·spring boot·java-ee·mybatis
吴声子夜歌16 小时前
Java数据结构与算法——基本数学问题
java·开发语言·windows
这儿有一堆花19 小时前
用原生脚本编写无害恶作剧
windows
因我你好久不见19 小时前
Windows部署springboot jar支持开机自启动
windows·spring boot·jar
夜流冰19 小时前
Excel - MS Support for Excel: 2 Collaborate
数据库·windows·excel
林瞅瞅20 小时前
PowerShell 启动卡顿?内存飙升?原来是 800MB 的历史记录在作祟!
windows
Shepherd061920 小时前
【Windows Server 实战】WAC 反向代理配置
windows
云小逸21 小时前
【windows系统编程】第一章 Windows 系统核心架构与基础概念
windows·架构
怣疯knight1 天前
Docker Desktop 4.55.0版本安装成功教程
windows·docker
liulilittle1 天前
VEthernet 框架实现 tun2socks 的技术原理
网络·windows·c#·信息与通信·通信