mybatis关于出现Parameter 'noList' not found. Available parameters are [collection, list]问题的解决方案

本文详细解析了在MyBatis中如何利用foreach动态SQL解决批量查询问题,阐述了参数传递、注解使用及集合遍历的正确姿势,帮助开发者避免常见错误。

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

当我们要查询一些人的信息时,但这些人的id是由用户确定的,就会采用list集合或者数组作为参数传入方法中,

public List findSomeUsers(List noList);

而在xml文件中就可以用Forreach动态SQL解决

<select id="findSomeUsers" resultType="user3" parameterType="list">
	select * from user where id in
	<foreach collection="noList" index="index" item="no" open="(" separator="," close=")">
		#{no}
	</foreach>
</select>

测试代码:

List<Integer> noList = new ArrayList<>();
noList.add(1);
noList.add(2);
noList.add(3);
noList.add(6);
List<User> list = mapper.findSomeUsers(noList);

结果却出错了,原因是找不到noList这个参数,为什么呢?
接着我在接口方法中的参数前面用注解的方式加上了@Param(“noList”),接着测试了一下,
结果并没有报错,且查出了结果
sql语句是select * from user where id in ( ? , ? , ? , ? )

User [id=1, name=张三, age=23]
User [id=2, name=李四, age=30]
User [id=3, name=张无忌, age=30]
User [id=6, name=张良, age=30]

然后上网查了一下,还有一种说法是:
因为 传递一个 List 实例或者数组作为参数对象传给 MyBatis,MyBatis 会自动将它包装在一个 Map 中,用名称在作为键。List 实例将会以“list” 作为键,而数组实例将会以“array”作为键

接着我恢复了之前发生错误的环境,把xml中的foreach中的collection改成了list,其他的都没改,没有报错,也可以查询出结果。

因此,解决这个异常的两种方式是:
1.在方法参数前面加上你遍历的集合的名称,比如你在foreach的collection中写的是noList,那么你就在传入的list参数前面加上一个注解@Param(“noList”)。
2.将foreach的collection中的值改成list即可。

### MyBatis 中 BindingException 错误的解决方案 当在 MyBatis 的 Mapper 文件中传递 `array` 或者集合类型(如 `List`, `Collection`)作为参数时,可能会遇到类似于以下错误: ``` org.apache.ibatis.binding.BindingException: Parameter 'statisticalInfoList' not found. Available parameters are [collection, list]. ``` 此错误表明,在 SQL 映射文件中使用的参数名称并未被正确识别。以下是详细的分析与解决方案。 #### 原因分析 MyBatis 在处理复杂数据结构(如数组或集合)时,会自动将其封装到一个内部的 `Map` 对象中[^4]。对于集合类型的参数,通常会被映射为以下几个键名之一: - `"arg0"`:表示第一个参数。 - `"collection"`:用于泛型集合对象。 - `"list"`:专用于 `java.util.List` 类型的对象。 如果在 XML 文件中指定的参数名称未匹配上述默认键名,则会出现 `BindingException` 错误。 --- #### 解决方案一:使用默认参数名称 无需修改 Java 方法签名的情况下,可以直接利用 MyBatis 提供的默认参数名称来访问集合内容。例如: ```xml <select id="findSomeUsers" resultType="User"> SELECT * FROM user WHERE id IN <foreach collection="list" item="id" open="(" separator="," close=")"> #{id} </foreach> </select> ``` 在此配置中,`collection="list"` 表示使用默认的 `"list"` 参数名称。这适用于大多数场景下的简单列表传递[^3]。 --- #### 解决方案二:显式声明参数名称 通过在接口方法上添加 `@Param` 注解,可以自定义参数名称并确保其一致性。例如: ```java public interface UserMapper { List<User> findSomeUsers(@Param("noList") List<Integer> noList); } ``` 对应的 XML 配置应改为: ```xml <select id="findSomeUsers" resultType="User"> SELECT * FROM user WHERE id IN <foreach collection="noList" item="id" open="(" separator="," close=")"> #{id} </foreach> </select> ``` 这种方式能够有效避免命名冲突,并提高代码可读性和维护性[^2]。 --- #### 解决方案三:混合多参数情况 当需要同时传递多个不同类型的参数(如整数和列表)时,可以通过组合方式解决绑定异常问题。例如: ```java void insertList( @Param("planId") Integer planId, @Param("projectPlans") List<ProjectPlan> projectPlans ); ``` XML 配置需分别引用这些参数: ```xml <insert id="insertList"> INSERT INTO table_name (column1, column2) VALUES ( #{planId}, <foreach collection="projectPlans" item="plan" separator=","> #{plan.someField} </foreach> ) </insert> ``` 这种方法特别适合涉及复合条件查询或多表联结的情况[^5]。 --- #### 示例代码展示 下面是一个完整的例子,演示如何安全地向 MyBatis 传递集合类型参数而不引发 `BindingException`。 Java 接口定义: ```java import org.apache.ibatis.annotations.Param; public interface ExampleMapper { List<String> selectNamesByIds(@Param("ids") List<Integer> ids); } ``` SQL 映射文件 (`ExampleMapper.xml`): ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.ExampleMapper"> <select id="selectNamesByIds" resultType="String"> SELECT name FROM users WHERE id IN <foreach collection="ids" item="id" open="(" separator="," close=")"> #{id} </foreach> </select> </mapper> ``` 调用逻辑: ```java List<Integer> userIds = Arrays.asList(1, 2, 3); List<String> names = exampleMapper.selectNamesByIds(userIds); System.out.println(names); ``` --- ### 总结 为了防止 `BindingException` 发生,建议遵循以下原则: 1. 使用 MyBatis 默认支持的关键字(如 `list`, `collection`)。 2. 如果需要更灵活的控制,推荐采用 `@Param` 注解明确指定参数名称。 3. 处理多参数输入时,务必逐一标注各变量的作用域及其含义。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值