文章目錄
- 背景
- 什么是@Param
- @Param的使用方法使用方法:
- 遇到的問題及因
- @Param解決了什么問題
- 使用與不使用對比
- @Param是如何進行映射的
- 總結
背景
最近在開發過程中,在寫mapper接口是在參數前加了@Param注解,但是在運行的時候就會報錯,說是找不到參數、
nested exception is org.apache.ibatis.binding.BindingException: Parameter ‘defaultRole’ not found. Available parameters are [role, param1]
什么是@Param
@Param注解是一種用于標記方法參數的注解,它用于指定該參數的名稱和類型,在使用該參數時可以通過名稱來引用。在不同的編程語言和框架中,@Param注解的具體用法和功能可能會有所不同。
在Java開發中,如果用到了mybatis,那么@Param是用戶給方法參數指定一個名稱,以便在Mapper XML文件中引用該參數。
@Param的使用方法使用方法:
當使用MyBatis框架時,@Param注解有以下幾種使用方法:
1、在Mapper接口方法的參數前使用@Param注解指定參數名稱:
void insertUser(@Param("user") User user);
在Mapper XML文件中可以使用#{user}來引用參數。
2、在Mapper接口方法的參數前使用@Param注解指定多個參數名稱:
void insertUserAndRole(@Param("user") User user, @Param("role") Role role);
在Mapper XML文件中可以使用#{user}和#{role}來引用參數。
3、在Mapper接口方法的參數前使用@Param注解指定相同的參數名稱:
void insertUsers(@Param("users") List<User> users);
在Mapper XML文件中可以使用#{users}來引用參數。
4、在Mapper接口方法的參數前使用@Param注解指定多個相同的參數名稱:
void insertUserAndRoles(@Param("users") List<User> users, @Param("roles") List<Role> roles);
在Mapper XML文件中可以使用#{users}和#{roles}來引用參數。
5、在Mapper接口方法的參數前不使用@Param注解:
void insertUser(User user);
在Mapper XML文件中可以使用#{arg0}來引用參數,或者把#{arg0}替換為#{user}
6、在Mapper接口方法的參數前不使用@Param注解,但有多個參數:
void insertUserAndRole(User user, Role role);
在Mapper XML文件中可以使用#{arg0}和#{arg1}來引用參數。
這些是@Param注解的常見使用方法。通過使用@Param注解,可以明確指定Mapper接口方法參數的名稱,使得在Mapper XML文件中引用參數更加直觀和可讀。
原理:
@Param注解的作用是給Mapper接口方法的參數命名,以便在Mapper XML文件中引用這些參數。沒有@Param注解時,MyBatis無法識別參數的名稱,導致無法正確引用參數。
在編譯時,Java編譯器會將@Param注解保留在編譯后的字節碼文件中。MyBatis通過Java的反射機制獲取Mapper接口方法的參數列表,并檢查是否存在@Param注解。
當解析Mapper XML文件時,MyBatis會根據#{}占位符中的名稱來查找對應的參數。如果找不到與占位符名稱匹配的參數,MyBatis會拋出BindingException異常。
遇到的問題及因
這是我寫的mapper接口:
int setDefaultRole( List<SysRole> roleList);
以及xml文件:
<update id="setDefaultRole" >update sys_role<set><foreach collection="roleList" item="role" separator=",">default_role=#{role.defaultRole},update_by=#{role.updateBy},update_time=sysdate()</foreach></set>where role_id in<foreach collection="roleList" item="role" open="(" close=")" separator=",">#{role.roleId}</foreach>and del_flag=0</update>
那么在xml文件中用到了多個關于roleList的多個參數,所以這里如果不使用@Param注解是不可以,他不能對應上對應的參數
這個錯誤通常是由于Mapper接口方法的參數和Mapper XML文件中的參數名不一致導致的。
@Param解決了什么問題
@Param注解主要解決了以下兩個問題:
解決多個參數的問題: 在Mapper接口方法中,如果存在多個參數,MyBatis默認會將這些參數封裝為一個Map對象,并以參數名作為鍵,參數值作為值。但是,當需要在Mapper XML文件中引用這些參數時,就需要使用#{}占位符,并指定對應的參數名。而@Param注解可以明確指定參數的名稱,使得在Mapper XML文件中引用參數更加直觀和可讀。
解決參數名與Mapper XML文件中占位符名稱不一致的問題: 在Mapper XML文件中,使用#{}占位符來引用參數,占位符中的名稱應該與Java代碼中的參數名稱一致。但是,Java編譯器在編譯時會將參數名擦除,導致在運行時無法獲取參數的名稱。而@Param注解可以保留參數的名稱,并在運行時通過反射機制獲取參數的名稱,從而確保參數名與占位符名稱一致。
通過使用@Param注解,可以提高Mapper接口方法的可讀性和可維護性,避免了潛在的錯誤。它確保了Mapper XML文件中的參數引用與Java代碼中的參數名稱一致。
使用與不使用對比
使用@Param注解和不使用的區別主要體現在Mapper接口方法的參數映射上。
不使用@Param注解:
void insertUser(User user);
在Mapper接口方法中,直接使用參數對象作為方法的參數,例如User user。在Mapper XML文件中,可以使用#{}占位符來引用參數的屬性,例如#{id}和#{name}。
使用@Param注解:
void insertUser(@Param(“user”) User user);
在Mapper接口方法中,使用@Param注解來明確指定參數的名稱,例如@Param(“user”)。在Mapper XML文件中,可以使用#{}占位符來引用參數,占位符中的名稱應與@Param注解中指定的名稱一致,例如#{user.id}和#{user.name}。
使用@Param注解的優勢是可以提高Mapper接口方法的可讀性和可維護性。通過明確指定參數的名稱,可以確保參數名與占位符名稱一致,避免因為參數順序變化或者重載方法導致的錯誤。
總結起來,使用@Param注解可以提高Mapper接口方法的可讀性和可維護性,確保參數名與占位符名稱一致,而不使用@Param注解則直接使用參數對象作為方法的參數。
@Param是如何進行映射的
當使用@Param注解時,MyBatis會通過反射機制獲取Mapper接口方法的參數信息,包括參數的名稱和類型。然后,MyBatis會將這些參數信息與方法的參數列表進行關聯,以便后續在Mapper XML文件中引用這些參數。
具體的映射過程如下:
在Mapper接口方法上使用@Param注解,并指定參數的名稱。例如:
void insertUser(@Param("user") User user);
這里使用@Param(“user”)注解明確指定了參數的名稱為"user"。
MyBatis解析Mapper接口方法時,會通過反射獲取方法的參數信息,包括參數的名稱和類型。這是通過Java的反射機制實現的。
在解析Mapper XML文件時,MyBatis會使用ParamNameResolver類來解析占位符中的參數名稱。ParamNameResolver會根據方法的參數列表和參數名稱,確定參數的映射關系。
在Mapper XML文件中,可以使用#{}占位符來引用參數。占位符中的名稱應與Java代碼中的參數名稱一致。例如:
<insert id="insertUser" parameterType="com.example.User">INSERT INTO user (id, name) VALUES (#{user.id}, #{user.name})
</insert>
這里使用#{user.id}和#{user.name}來引用參數。
通過以上過程,@Param注解實現了參數名稱與Mapper XML文件中占位符名稱的映射關系。這樣可以提高Mapper接口方法的可讀性和可維護性,確保參數名與占位符名稱一致。
總的來說,@Param注解的工作原理是通過反射機制獲取參數信息,并將參數名稱與方法的參數列表進行關聯,以確保參數名與占位符名稱一致。這樣可以提高Mapper接口方法的可讀性和可維護性。
總結
總結起來,@Param注解用于在Mapper接口方法中明確指定參數的名稱,以提高方法的可讀性和可維護性。以下是關于@Param注解的優缺點的總結:
優點:
明確參數名稱:使用@Param注解可以明確指定參數的名稱,避免參數順序變化或者重載方法導致的錯誤。這樣可以提高代碼的可讀性和可維護性。
參數與占位符一致:@Param注解可以確保參數名與Mapper XML文件中的占位符名稱一致,避免因為參數名與占位符不一致而引發的錯誤。
缺點:
冗余代碼:使用@Param注解會在Mapper接口方法中增加注解的代碼,可能會導致代碼的冗余。
額外的注解:使用@Param注解需要在Mapper接口方法中添加額外的注解,可能會增加代碼的復雜性。
@Param注解可以提高Mapper接口方法的可讀性和可維護性,確保參數名與占位符名稱一致。然而,使用@Param注解可能會導致代碼的冗余,同時也需要額外的注解。因此,在使用@Param注解時,需要根據具體情況進行權衡和取舍。