foreach 核心屬性解析
<foreach> 主要用於構建 IN 條件,核心屬性:
collection:要遍歷的集合(**最關鍵**,值根據參數類型不同而異)
item:遍歷時的別名
index:索引別名
open / close / separator:SQL 片段包裹符號
三種參數類型的 collection 值對照表
| 傳入參數類型 | collection 屬性值 | 說明 |
| 單參數 List | list | MyBatis 自動包裝為 map,key 為 "list" |
| 單參數 Array | array | MyBatis 自動包裝為 map,key 為 "array" |
| 多參數 / Map | Map 中對應的 key | 需手動封裝 Map,key 自定義 |
實戰代碼範例
1. 單參數 List
<!-- Mapper XML -->
<select id="getEmployeesListParams" resultType="Employees">
SELECT * FROM EMPLOYEES e
WHERE e.EMPLOYEE_ID IN
<foreach collection="list" item="employeeId" open="(" close=")" separator=",">
#{employeeId}
</foreach>
</select>
<!-- Mapper 介面 -->
List<Employees> getEmployeesListParams(List<String> employeeIds);
2. 單參數 Array
<select id="getEmployeesArrayParams" resultType="Employees">
SELECT * FROM EMPLOYEES e
WHERE e.EMPLOYEE_ID IN
<foreach collection="array" item="employeeId" open="(" close=")" separator=",">
#{employeeId}
</foreach>
</select>
List<Employees> getEmployeesArrayParams(String[] employeeIds);
3. Map 封裝多參數(推薦企業級開發)
<select id="getEmployeesMapParams" resultType="Employees">
SELECT * FROM EMPLOYEES e
<where>
<if test="departmentId != null and departmentId != ''">
e.DEPARTMENT_ID = #{departmentId}
</if>
<if test="employeeIdsArray != null and employeeIdsArray.length != 0">
AND e.EMPLOYEE_ID IN
<foreach collection="employeeIdsArray" item="employeeId" open="(" close=")" separator=",">
#{employeeId}
</foreach>
</if>
</where>
</select>
List<Employees> getEmployeesMapParams(Map<String, Object> params);
Java 呼叫範例
Map<String, Object> params = new HashMap<>();
params.put("departmentId", "10");
params.put("employeeIdsArray", new String[]{"100", "101", "102"});
List<Employees> emps = mapper.getEmployeesMapParams(params);
最佳實踐建議
- **優先使用 Map 封裝**:參數名稱語義化,擴展性強,避免單參數限制
- **@Param 註解替代**:Mapper 介面使用
@Param("ids") List<String> ids,XML 中 collection="ids"
- **空集合防護**:配合
<if test="list != null and list.size > 0"> 避免 SQL 語法錯誤
- **大集合分批**:Oracle IN 限制 1000 個元素,超過需分批或使用臨時表
常見錯誤排查
| 錯誤現象 | 原因 | 解決 |
| Parameter 'list' not found | 單參數 List 但 XML 用了自定義 key | 改用 collection="list" 或加 @Param |
| SQL 語法錯誤 near ')' | 集合為空導致 IN () | 加 <if> 判空 |
| Type mismatch | item 類型與集合泛型不符 | 確保 #{item} 類型匹配 |