- 概述
- MyBatis 的
foreach标签用于在 SQL 语句中遍历集合(如List、Set等)或数组,它提供了一种方便的方式来动态生成 SQL 片段,比如批量插入、批量更新或根据一组条件进行查询等操作。
- 基本语法结构
foreach标签通常包含以下属性:
collection:指定要遍历的集合或数组。这个属性的值可以是方法参数中的集合名称、Map中的键(如果参数是Map且集合作为值存储在Map中)等。item:表示集合或数组中的每个元素在遍历过程中的别名。在 SQL 语句中可以使用这个别名来引用元素。index:可选属性,用于表示当前元素在集合或数组中的索引位置(对于数组和List等有序集合),可以在 SQL 语句中使用这个索引。open:可选属性,用于指定遍历开始时添加的 SQL 片段,比如在批量插入时可能是("INSERT INTO table (column1, column2) VALUES"。close:可选属性,用于指定遍历结束时添加的 SQL 片段,例如在批量插入时可能是)。separator:可选属性,用于指定每个元素之间的分隔符,在批量插入中可能是),(,用于分隔每个VALUES子句。
- 批量插入示例
- 假设我们有一个
List<User>,其中User是一个包含name和age属性的 Java 类,我们想将这些用户信息批量插入到数据库的user表中。 - Mapper 接口方法定义可能如下:
void batchInsert(List<User> userList);
- Mapper XML 中的 SQL 语句可以这样写:
<insert id="batchInsert"> INSERT INTO user (name, age) VALUES <foreach collection="userList" item="user" separator=","> (#{user.name}, #{user.age}) </foreach> </insert>
- 在这个示例中:
collection属性的值是userList,这是传入方法的List<User>的名称。item属性的值是user,表示userList中的每个User对象在 SQL 语句中可以用user来指代。separator属性的值是,,用于在每个VALUES子句之间添加逗号进行分隔。- 这样,MyBatis 会根据
userList中的元素数量动态生成批量插入的 SQL 语句。
- 根据条件列表查询示例
- 假设我们有一个
List<Integer>,其中包含用户 ID,我们想查询这些用户的信息。 - Mapper 接口方法定义:
List<User> findUsersByIdList(List<Integer> idList);
- Mapper XML 中的 SQL 语句:
<select id="findUsersByIdList"> SELECT * FROM user WHERE id IN <foreach collection="idList" item="id" open="(" close=")" separator=","> #{id} </foreach> </select>
- 在这里:
collection属性的值是idList,代表传入的包含用户 ID 的List。item属性是id,用于在 SQL 语句中引用idList中的每个 ID。open和close属性分别是(和),用于包围IN操作符后的条件列表。separator属性是,,用于分隔每个 ID,这样就可以正确地构建IN条件查询的 SQL 语句。
- 遍历 Map 示例
- 如果参数是
Map类型,并且Map中包含集合作为值,foreach标签也可以很好地工作。假设Map的键是category,值是List<Integer>,表示每个类别下的产品 ID 列表,我们想查询每个类别下的产品。 - Mapper 接口方法定义:
List<Product> findProductsByCategory(Map<String, List<Integer>> categoryMap);
- Mapper XML 中的 SQL 语句:
<select id="findProductsByCategory"> SELECT * FROM product WHERE <foreach collection="categoryMap" item="idList" key="category"> (category = #{category} AND id IN <foreach collection="idList" item="id" open="(" close=")" separator=","> #{id} </foreach> ) OR </foreach> 1 = 0 </select>
- 在这个复杂的示例中:
- 外层
foreach遍历categoryMap,key属性指定了Map的键(category)作为 SQL 语句中的一个条件,item属性指定了Map的值(idList),这是一个包含产品 ID 的List。 - 内层
foreach用于遍历每个类别下的产品 ID 列表,构建IN条件,和前面的IN查询示例类似。 - 最后添加
1 = 0是为了在最后一个OR条件后使整个WHERE语句语法正确,因为如果没有这个,最后一个OR条件会导致语法错误。这是一种常用的技巧来确保 SQL 语句的正确性。