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 的编写。

相关推荐
阿尼卡~7 小时前
VS Code 配置 C 语言开发环境(Windows 10/11):从 GCC 安装到运行、断点调试,一篇搞定
c语言·开发语言·windows
liyi_hz200811 小时前
O2OA(翱途) V10.1 即将发布|功能再升级,安全再加固,协同更高效!
java·javascript·windows·开源软件
七牛云行业应用13 小时前
DeepSeek Harness(dsh)安装完整指南:Windows、macOS、Linux 三平台 + 桌面端与 Web 端全覆盖
linux·windows·macos·ai·ai编程
起个名字都难啊16 小时前
visual studio C/C++空项目修改为CUDA c++
c++·windows·visual studio
xixiaoyunya17 小时前
轻量级 Windows 文件共享方案实测:零配置部署私有网盘,兼容全平台浏览器访问
windows
垆边人似月.18 小时前
第二篇:列表、字典与流程控制 / Lists, Dictionaries & Control Flow
windows
代码不停18 小时前
MyBatis操作数据库
数据库·mybatis
呉師傅18 小时前
Win7剪切文件变成复制文件如何修改【资源管理器异常类故障】
运维·网络·windows·电脑
略略略咯咯19 小时前
33333
开发语言·windows·python
wno70419 小时前
Spring Boot中JdbcTemplate与Mybatis使用PostgreSQL
spring boot·postgresql·mybatis