Mapper XML 中使用 <foreach> 遍歷參數,傳入實體類別正常,改傳 Map 或 List<Map> 後無法取值。
collection 屬性值必須為參數名稱(或參數對象內的屬性名),不是 Java 型別名稱。item 代表迴圈當前元素,index 為索引。Map 時,用 #{item.key} 取值;元素為實體時,用 #{item.property}。| Java 參數 | collection 值 | item 取值方式 |
|---|---|---|
List<User> users | collection="users" | #{item.id}, #{item.name} |
List<Map> list | collection="list" | #{item.keyName} |
Map<String, List<User>> map key="userList" | collection="userList" | #{item.id} |
@Param("ids") List<Long> ids | collection="ids" | #{item} (基本型別直接用 item) |
單一 Map 參數(無 @Param) | collection="map.key" 或直接用 key | 視 Map value 型別而定 |
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO t_user (name, age, email)
VALUES
<foreach collection="list" item="item" index="idx" separator=",">
(#{item.name}, #{item.age}, #{item.email})
</foreach>
</insert>
Java 呼叫:
List<Map<String, Object>> list = new ArrayList<>();
list.add(Map.of("name", "A", "age", 18, "email", "a@x.com"));
list.add(Map.of("name", "B", "age", 20, "email", "b@x.com"));
mapper.batchInsert(list); // 參數名即為 "list"(單一參數時 MyBatis 自動以 "list"/"collection" 綁定)
| 錯誤寫法 | 問題 | 修正 |
|---|---|---|
collection="java.util.List" | 寫了型別名稱,非參數名 | collection="list" 或 collection="paramName" |
#{item.get('key')} | OGNL 不支援 Map.get() | #{item.key} |
| 單一 Map 參數未加 @Param | MyBatis 以 "map"/"parameter" 綁定,易混淆 | 加 @Param("myMap"),XML 用 collection="myMap.keyList" |
foreach 缺少 separator="," | SQL 語法錯誤(值之間無逗號) | 必加 separator="," |
<foreach collection="list" item="t" separator=";">
INSERT INTO ${t.tableName} (col1) VALUES (#{t.val})
</foreach>
${...} 為直接字串替換(有 SQL 注入風險),僅用於受信任的內部參數(如代碼生成階段)。
logging.level.org.apache.ibatis=DEBUG,查看實際 SQL 與參數綁定。<bind name="debug" value="@java.lang.System@out.println('item=' + item)" /> 列印迴圈變數。SqlSessionFactoryBuilder 單元測試,斷點檢查 BoundSql。