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

相关推荐
甄超锋25 分钟前
Java ArrayList的介绍及用法
java·windows·spring boot·python·spring·spring cloud·tomcat
cpsvps3 小时前
美国服务器环境下Windows容器工作负载基于指标的自动扩缩
windows
网硕互联的小客服5 小时前
Apache 如何支持SHTML(SSI)的配置方法
运维·服务器·网络·windows·php
etcix6 小时前
implement copy file content to clipboard on Windows
windows·stm32·单片机
许泽宇的技术分享6 小时前
Windows MCP.Net:基于.NET的Windows桌面自动化MCP服务器深度解析
windows·自动化·.net
非凡ghost7 小时前
AMS PhotoMaster:全方位提升你的照片编辑体验
windows·学习·信息可视化·软件需求
mortimer9 小时前
一次与“顽固”外部程序的艰难交锋:subprocess 调用exe踩坑实录
windows·python·ai编程
gameatp11 小时前
从 Windows 到 Linux 服务器的全自动部署教程(免密登录 + 压缩 + 上传 + 启动)
linux·服务器·windows
穷人小水滴11 小时前
在 windows 运行 flatpak 应用 (WSL)
linux·windows·ubuntu
昵称为空C1 天前
SpringBoot 实现DataSource接口实现多租户数据源切换方案
后端·mybatis