MyBatis 映射文件中 #{...} 參數綁定規則靈活但易混淆。本文系統整理單參數、多參數、複雜對象、List 集合等場景的正確寫法,並給出統一推薦規範。
直接使用:參數名任意,#{任意名} 均可(建議與方法參數名一致)。
// Mapper
List<User> selectById(Long id);
// XML
SELECT * FROM user WHERE id = #{id}
@Param 顯式命名:@Param("uid") Long id → XML 用 #{uid}。推薦:所有公開介面均加 @Param,避免編譯參數名丟失(未加 -parameters 時)。
直接使用:#{屬性名} 自動映射對象屬性。
// Mapper
List<User> selectByCondition(UserQuery query);
// XML
SELECT * FROM user
WHERE name = #{name} AND age > #{age}
@Param 包裝:@Param("q") UserQuery query → XML 必須 #{q.name}、#{q.age},不可簡寫#{name}。
不加 @Param(不推薦):依賴編譯器保留參數名(需 javac -parameters),XML 用 #{param1}、#{param2} 或 #{0}、#{1}(索引從 0 開始)。
加 @Param(強烈推薦):
// Mapper
List<User> select(@Param("name") String name, @Param("age") Integer age);
// XML
SELECT * FROM user WHERE name = #{name} AND age = #{age}
規則:複雜對象必須加 @Param,基礎類型建議同步加 @Param。
// Mapper
List<User> select(@Param("q") UserQuery q, @Param("status") Integer status);
// XML
SELECT * FROM user
WHERE name = #{q.name} AND age > #{q.age} AND status = #{status}
錯誤示範:UserQuery q, Integer status(無 @Param)→ MyBatis 無法區分,會報錯或綁定錯誤。
// Mapper
List<User> select(@Param("id") Long id, @Param("q") UserQuery q);
// XML
WHERE id = #{id} AND name = #{q.name}
// Mapper
List<User> selectByIds(@Param("ids") List<Long> ids);
// XML
SELECT * FROM user WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
collection 屬性值 = @Param 值(此處 "ids")。
// Mapper
int batchInsert(@Param("users") List<User> users);
// XML
INSERT INTO user (name, age) VALUES
<foreach collection="users" item="u" separator=",">
(#{u.name}, #{u.age})
</foreach>
| 場景 | 是否必加 @Param | XML 寫法 | 備註 |
|---|---|---|---|
| 單基礎類型 | 建議加 | #{paramName} | 防參數名丟失 |
| 單複雜對象 | 可不加 | #{prop} | 加了則需 #{param.prop} |
| 多基礎類型 | 必加 | #{paramName} | 否則靠索引/編譯參數名,極不穩 |
| 多參數含對象 | 必加(對象) | #{param.prop} / #{paramName} | 基礎類型同步加 @Param 更清晰 |
| List/集合 | 必加 | collection="paramName" | foreach 依賴 collection 名稱 |
#{q.xxx}。mapUnderscoreToCamelCase=true,資料庫下劃線自動映射駝峰屬性。#{param} 找不到值 → 檢查 @Param 拼寫、編譯是否保留參數名。foreach 報 Collection not found → collection 屬性必須等於 @Param 值,而非 Java 參數變數名。<if test="q.name != null"> 動態 SQL。遵循「統一 @Param、單一 Query Object、foreach 綁定 collection」三原則,可消除 90% 以上 MyBatis 參數綁定問題。