Mybatis @Param参数传递说明

MyBatis 在各个参数场景下,不同数据类型的默认参数名及使用规则的详细总结:

一、基础数据类型(非集合/非数组)

包含类型String、Integer、Long、Boolean、Double 等包装类及基本类型(如 int、long)。

默认参数名规则:
  • 无需指定参数名,MyBatis 会直接绑定唯一参数值。
  • XML 中 #{任意名称} 均可生效(名称仅作为占位符,不影响绑定)。
示例:
java 复制代码
// Mapper 接口(无 @Param)
User selectByUsername(String username);
xml 复制代码
<!-- XML 映射(任意名称均可) -->
<select id="selectByUsername" resultType="User">
  SELECT * FROM user WHERE username = #{name}  <!-- 可用 username/abc/任意名称 -->
</select>
特点:
  • 绝对不会报错(只要参数类型匹配),无需担心"参数找不到"问题。
  • 推荐:虽然可省略 @Param,但复杂场景下建议添加以增强可读性(如 @Param("username"))。

二、集合类型(Collection 及其子类)

包含类型List、Set、Collection 等。

默认参数名规则:
  • MyBatis 会自动赋予默认名称:
    • Collection 及其子类通用默认名:collection
    • List 类型额外支持 list 作为名称(更常用)
示例:
java 复制代码
// Mapper 接口(无 @Param)
List<User> selectByIds(List<Long> ids);
xml 复制代码
<!-- XML 映射(必须用默认名) -->
<select id="selectByIds" resultType="User">
  SELECT * FROM user WHERE id IN
  <foreach collection="list" item="id" open="(" separator="," close=")">  <!-- 用 list 或 collection -->
    #{id}
  </foreach>
</select>
注意:
  • 如果 XML 中用了非默认名(如 collection="ids"),会直接报错 Parameter 'ids' not found
  • 解决:添加 @Param("ids") 注解,XML 中即可用 collection="ids"

三、数组类型

包含类型String[]、Integer[]、Long[] 等任意数组。

默认参数名规则:
  • 固定默认名称为 array,无其他可选名称。
示例:
java 复制代码
// Mapper 接口(无 @Param)
List<User> selectByRoles(String[] roles);
xml 复制代码
<!-- XML 映射(必须用 array) -->
<select id="selectByRoles" resultType="User">
  SELECT * FROM user WHERE role IN
  <foreach collection="array" item="role" open="(" separator="," close=")">
    #{role}
  </foreach>
</select>
注意:
  • 若 XML 中用 list 或自定义名(如 roles),会报错 Parameter 'xxx' not found
  • 解决:添加 @Param("roles") 注解,XML 中即可用 collection="roles"

四、JavaBean/自定义对象

包含类型 :自定义实体类(如 User、Order)、Map 等。

默认参数名规则:
  • 直接使用对象的属性名作为参数名(无需指定默认名)。
  • Map 类型直接使用 key 作为参数名。
示例:
java 复制代码
// Mapper 接口(无 @Param)
void updateUser(User user);  // User 有 id、username 等属性
xml 复制代码
<!-- XML 映射(直接用属性名) -->
<update id="updateUser">
  UPDATE user 
  SET username = #{username}, age = #{age} 
  WHERE id = #{id}  <!-- 直接引用 User 的属性 -->
</update>
特点:
  • 无需关心参数名,直接通过对象属性绑定,不会报错。
  • 若用 @Param("user") 注解,XML 中需用 #{user.username} 引用(不推荐,徒增复杂度)。

五、特殊场景:多参数(即使包含单个集合/数组)

当方法有多个参数时,无论类型如何,必须用 @Param 注解指定名称 ,否则 MyBatis 无法识别参数名,只能用 arg0、arg1param1、param2 引用(不推荐)。

示例:
java 复制代码
// 错误写法(多参数无 @Param)
List<User> selectByCondition(String name, List<Long> deptIds);  // 会报错

// 正确写法(用 @Param 区分)
List<User> selectByCondition(
  @Param("name") String name, 
  @Param("deptIds") List<Long> deptIds
);
xml 复制代码
<!-- XML 映射(用注解指定的名称) -->
<select id="selectByCondition" resultType="User">
  SELECT * FROM user 
  WHERE name LIKE #{name} 
  AND dept_id IN 
  <foreach collection="deptIds" item="id" open="(" separator="," close=")">
    #{id}
  </foreach>
</select>

总结表格

参数类型 无 @Param 时的默认名称 XML 中引用示例 是否可能报错
基础类型(String、Integer等) 无(任意名称均可) #{任意名称} 不会报错
List/Collection collection、list(List特有) #{list[0]}、foreach collection="list" 用错名称会报错
数组(String[]、Integer[]等) array foreach collection="array" 用错名称会报错
JavaBean/Map 直接用属性名/key #{username}、#{mapKey} 不会报错
多参数(任意类型) arg0、arg1 或 param1、param2 #{arg0}、#{param1} 不用 @Param 必报错

最佳实践

  1. 基础类型单参数:可省略 @Param,但建议添加以增强代码可读性。
  2. 集合/数组单参数:必须添加 @Param (如 @Param("ids")),避免依赖默认名导致的潜在问题。
  3. 多参数:强制添加 @Param,明确区分每个参数。
  4. JavaBean/Map:无需添加 @Param,直接用属性名引用即可。

遵循以上规则可避免 99% 的 MyBatis 参数绑定错误。