在 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 的編寫。