在使用 MyBatis 註解開發時,初學者常遇到一個經典錯誤:Parameter 'name' not found. Available parameters are [1, 0, param1, param2]。這通常發生在使用 @Select 等 SQL 註解時,嘗試在 SQL 語句中直接使用方法參數名稱(如 #{name})進行綁定。本文將深入分析錯誤原因,並提供多種解決方案。
假設我們有一個用戶登錄查詢的 Mapper 接口:
// 登錄·查詢
@Select("select * from t_users where uname=#{name} and pswd=#{pswd}")
public Users findByNP(String name, String pswd);
運行測試時,控制台拋出異常:
Parameter 'name' not found. Available parameters are [1, 0, param1, param2]
MyBatis 在解析註解時,無法直接獲取方法參數的名稱(Java 編譯後參數名稱會丟失,除非編譯時加入 -parameters 選項)。因此,MyBatis 預設將參數按位置索引(0, 1...)或通用名稱(param1, param2...)存放在 Map 中。當 SQL 中使用 #{name} 時,MyBatis 在參數 Map 中找不到 key 為 "name" 的值,從而報錯。
直接在 SQL 中使用 #{0}, #{1} 代表第一、第二個參數:
@Select("select * from t_users where uname=#{0} and pswd=#{1}")
public Users findByNP(String name, String pswd);
缺點:可讀性差,參數順序一旦調整容易出錯。
為每個參數顯式指定名稱,這是官方推薦且最常用的方式:
@Select("select * from t_users where uname=#{username} and pswd=#{password}")
public Users findByNP(@Param("username") String name, @Param("password") String pswd);
優點:語義清晰,解耦參數名與方法簽名,易於維護。
在 pom.xml 中配置 maven-compiler-plugin,加入 <compilerArgument>-parameters</compilerArgument>。此後可直接使用參數名,無需 @Param。但需注意團隊統一 JDK 版本及 IDE 設置。
「Parameter not found」本質是 MyBatis 無法獲取參數名。掌握 @Param 與位置索引兩種綁定方式,即可輕松解決此類問題,編寫出健壯、可維護的數據訪問層代碼。