@Param注解在mybatis中的使用以及传入参数的几种方式(转)

本文介绍了使用MyBatis进行多参数查询的四种方法,包括直接传递参数、使用Map传递参数、使用@param注解指定参数名称及传递User对象作为参数等不同方式,并详细展示了对应的Dao层方法与Mapper.xml配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一种:

Dao层的方法

<span style="font-size:12px;">Public User selectUser(String name,String password);</span>  

 

对应的Mapper.xm

  

<select id="selectUser" resultMap="BaseResultMap">  

    select  *  from user_user_t   where user_name = #{0} and user_password=#{1}  

  </select>  

 


第二种:

 

该方法采用Map传多参数

Dao层的方法

 

<span style="font-size:12px;">Public User selectUser(Map paramMap);</span>  

 

对应的Mapper.xml

 <select id=" selectUser" resultMap="BaseResultMap">  
  select * from user_user_t where user_name = #{userName,jdbcType=VARCHAR} and user_password=#{userPassword,jdbcType=VARCHAR}
 </select>

 

  

Service层调用

 

 

public User xxxSelectUser(){  

Map paramMap=new hashMap();  

paramMap.put(“userName”,”对应具体的参数值”);  
paramMap.put(“userPassword”,”对应具体的参数值”);  
User user=xxx. selectUser(paramMap);} 

 

 

个人认为此方法不够直观,见到接口方法不能直接的知道要传的参数是什么。

 

第三种:

Dao层的方法

Public User selectUser(@param(“userName”)Stringname,@param(“userpassword”)String password);

 

对应的Mapper.xml

<select id=" selectUser" resultMap="BaseResultMap">  

   select  *  from user_user_t   where user_name = #{userName,jdbcType=VARCHAR} and user_password=#{userPassword,jdbcType=VARCHAR} 

</select>

 

第四种:

mapper.java:

public List<User> getUserByParam(User use);

 

 

对应Mapper.xml:

<select id="getUserByParam" resultType="com.ray.bean.User" parameterType="com.ray.bean.User" > 
    select * from t_pub_user t 
     <where>
        <if test="{user_name}!=null">
             t.user_name like CONCAT('%',#{user_name},'%')
        </if>
        <if test="{user_password}!=null">
            and t.user_password like CONCAT('%',#{user_password},'%')
        </if>
    </where>
     limit #{1},#{2} 
</select>

 

<think>我们正在讨论MyBatis@Param注解在传递集合参数时的作用和用法。根据引用内容,@Param注解主要用于为方法参数命名,以便在MyBatis的SQL映射中引用。当参数是集合时,这个注解同样重要。 引用[1]指出,@Param注解帮助映射方法的多个参数,使它们在SQL语句中有明确的名字。如果没有@ParamMyBatis会将多个参数打包成一个Map,但这样在SQL中引用就不够直观。引用[3]强调,当不使用@Param注解时,MyBatis并不认识参数的名称,而是按照参数顺序进行映射,这可能导致问题。 对于集合参数(如List、Set、Map等),使用@Param注解可以给这个集合一个名字,这样在XML映射文件中就可以通过这个名字来访问这个集合。特别是在动态SQL中使用foreach标签时,我们需要指定collection属性,而这个属性值就是@Param注解中指定的名字。 例如,假设我们有一个查询方法,需要传入一个整数列表作为参数,用于IN子句: List<Student> findStudentsByIds(@Param("idList") List<Integer> ids); 在XML映射文件中,我们可以这样写: <select id="findStudentsByIds" resultType="Student"> SELECT * FROM student WHERE id IN <foreach item="id" collection="idList" open="(" separator="," close=")"> #{id} </foreach> </select> 这里,foreach标签的collection属性值为"idList",对应@Param("idList")中指定的名字。这样,MyBatis就知道要遍历的是参数中的idList集合。 如果不使用@Param注解,那么在默认情况下,对于单个集合参数MyBatis会将其视为一个特殊的对象,可以通过默认名称“list”或“collection”来引用(具体取决于MyBatis版本和配置),但这样可读性差且容易出错。对于多个参数,则必须使用@Param注解。 另外,引用[4]提到,如果接口方法有多个参数,并且使用@Param注解,那么在SQL语句中使用参数名就是注解中指定的value值。因此,对于集合参数使用@Param注解可以明确指定在SQL中引用的名称。 总结: 1. 当方法参数为集合类型,且需要在动态SQL(如foreach)中使用时,应使用@Param注解为其指定一个名称。 2. 在XML映射文件中,foreach标签的collection属性应设置为@Param注解中指定的名称。 3. 这样可以避免依赖默认的命名(如list、collection等),提高代码可读性和可维护性,同时避免多参数时的冲突。 注意:在MyBatis中,foreach标签的collection属性必须指定一个可迭代对象,而@Param注解就是为这个集合参数提供一个名字,以便在此处引用。 因此,使用@Param注解传递集合参数的作用主要是为了在MyBatis的SQL映射中能够通过名字明确引用该集合,特别是在动态SQL中。 接下来,我们生成相关问题。</think>### MyBatis `@Param` 注解在集合参数中的作用与用法 在 MyBatis 中,`@Param` 注解用于显式命名方法参数,确保参数在 SQL 映射中有明确标识。**当传递集合参数(如 `List`、`Set`、`Map`)时,`@Param` 的核心作用是解决多参数场景下的命名冲突问题,并确保动态 SQL(如 `foreach` 标签)能正确引用集合**。以下是详细解析: --- ### 一、`@Param` 注解的核心作用 1. **命名参数,避免歧义** MyBatis 默认通过参数位置(如 `param1`, `param2`)或类型别名(如 `list`)引用参数,易导致混淆。`@Param` 为集合提供显式名称,消除歧义[^1][^3]。 ```java // 无 @ParamMyBatis 默认用 "list" 或 "collection" 引用 List<User> selectUsers(List<Integer> ids); // 有 @Param:显式命名为 "idList" List<User> selectUsers(@Param("idList") List<Integer> ids); ``` 2. **支持多参数场景** 当方法包含多个参数时(如集合 + 其他对象),`@Param` 是必需的,否则 MyBatis 无法识别参数名称[^3][^4]: ```java // 错误:MyBatis 无法区分 ids 和 status List<User> selectUsers(List<Integer> ids, Integer status); // 正确:为每个参数命名 List<User> selectUsers( @Param("idList") List<Integer> ids, @Param("userStatus") Integer status ); ``` 3. **确保动态 SQL 正确引用集合** 在 `foreach` 标签中,`collection` 属性需明确指定集合名称。`@Param` 提供的名称直接用于此处[^1][^4]: ```xml <select id="selectUsers"> SELECT * FROM users WHERE id IN <!-- 使用 @Param 定义的名称 "idList" --> <foreach item="id" collection="idList" open="(" separator="," close=")"> #{id} </foreach> AND status = #{userStatus} <!-- 引用命名参数 --> </select> ``` --- ### 二、使用场景与最佳实践 #### 场景 1:单集合参数 即使只有一个集合参数,也建议使用 `@Param` 提高可读性: ```java // 显式命名更清晰 List<User> selectUsers(@Param("idList") List<Integer> ids); ``` 在 XML 中直接引用: ```xml <foreach collection="idList" ...> <!-- 非默认名 "list" 或 "collection" --> ``` #### 场景 2:多参数(含集合) 必须使用 `@Param` 区分不同参数[^3][^4]: ```java List<User> selectUsers( @Param("idList") List<Integer> ids, @Param("minAge") Integer minAge ); ``` XML 中安全引用: ```xml <where> <if test="minAge != null"> age >= #{minAge} </if> <if test="idList != null"> AND id IN <foreach collection="idList" item="id" ...> #{id} </foreach> </if> </where> ``` #### 场景 3:嵌套集合(如 `List<Map>`) 当集合元素为复杂对象时,`@Param` 确保层级访问: ```java List<User> selectUsers(@Param("filters") List<Map<String, Object>> filters); ``` XML 中使用: ```xml <foreach collection="filters" item="filter"> AND ${filter.column} = #{filter.value} </foreach> ``` --- ### 三、常见错误及解决方案 | **错误用法** | **后果** | **修复方案** | |----------------------------|----------------------------------|--------------------------------| | 省略 `@Param` 传递多参数 | MyBatis 抛出 `BindingException` | 为所有参数添加 `@Param` 注解 | | `foreach` 中使用默认名称 | 集合无法被识别 | 用 `@Param` 命名并显式引用 | | 混淆 `#{}` 和 `${}` 的引用 | SQL 注入风险 | 集合遍历用 `#{item}` 非 `${item}` | --- ### 四、总结 - **核心作用**:`@Param` 为集合参数提供显式名称,解决多参数场景下的命名冲突,确保动态 SQL(如 `foreach`)正确引用集合[^1][^3]。 - **最佳实践**: 1. 所有集合参数使用 `@Param` 命名; 2. 在 `foreach` 标签中,`collection` 属性值必须与 `@Param` 定义的名称一致; 3. 结合 `#{}` 预编译机制防止 SQL 注入[^4]。 - **安全提示**:即使使用 `@Param`,仍需在业务层验证集合内容(如元素类型、大小限制),并严格避免在 `${}` 中拼接用户输入[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值