MyBatis传递参数为集合时踩的坑
怎么回事#
这两天因为刚进组,拉到代码后用debug在了解项目的业务逻辑,其中有一个坑在当时让我百思不得其解,直到现在还有些疑问留在心中,所以打算写下来作为一个记录
既然是去了解业务逻辑,和数据库关联的操作肯定要重点关注。但是在使用postman发请求时,mybatis总是抛异常
org.apache.ibatis.binding.BindingException:Parameter '**'not found.Available parameters are[...]...
wtf?
看看代码咯#
mapper接口
// 怕被公司认出来,就对代码进行简单化处理,知道那么个意思就行
List<Object> getObjectsByIds(List<Integer> ids);
xml文件
<select id="getObjectsByIds" resultMap="baseResultMap">
select id,name from test_table where id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
这个功能其实很简单,就是传递一个id的list进去,根据id们去查询对应的object,乍一看没什么问题,但是有个地方却是踩坑的点
坑#
真正的坑需要同时结合接口和xml文件来看
List<Object> getObjectsByIds(List<Integer> ids)
<foreach collection="ids" item="id" open="(" separator="," close=")">
首先接口没加@Param
注解,xml文件中直接将collection
的值设置为ids,这里就不得不提一下mybatis在传递参数为集合时的机制了
首先看大家怎么说
collection属性必须指定,但是在不同情况下其值也不同
1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
3. 如果如果传入的是单参数且参数类型是一个Set集合的时候,collection的属性值不知道是什么,
遇到这种不知道的情况可以通过注解`@Param("set")`指定key值
4. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,
实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,
所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
翻译翻译就是,如果在mapper接口传递的参数不加@Param
,那么在xml中只能用它默认的属性值去接受,List就是list,Array就是array;如果在mapper接口中使用@Param
指定了名称,那在xml中就可以使用自己定义的名称去接收了
所以刚刚报错的原因就是既没有用注解表明自定义的名称,又没在xml中用MyBatis默认的属性值
改起来有两种方式
修改方式一#
mapper接口
List<Object> getObjectsByIds(@Param("ids") List<Integer> ids);
xml文件
<select id="getObjectsByIds" resultMap="baseResultMap">
select id,name from test_table where id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
修改方式二#
mapper接口
List<Object> getObjectsByIds(List<Integer> ids);
xml文件
<select id="getObjectsByIds" resultMap="baseResultMap">
select id,name from test_table where id in
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
总结#
两种修改方式都能让程序正常运行,但就我个人而言还是更喜欢方式一的修改,因为相比于参数在不同文件有不同名称,我还是更倾向于把所有名称都进行统一
多说一句#
我也查阅了一些资料,在MyBatis官方文档中并没有很明确的提及foreach
中collection到底怎么赋值,倒是官方提供的实例确实也是用的list进行的接收
有趣的是,我在文中提到的文档是根据各个论坛中的文章进行总结而成的,如果说大家确实在官方那里看到说collection具有默认值也欢迎评论
剩余的疑问#
尽管在我这把程序跑起来不抛异常了,但是我同事那里代码和我修改之前一模一样,但是他那边就可以正常运行,这个问题有了解的朋友欢迎留言,感谢!(跪了)
作者:colee51666
出处:https://www.cnblogs.com/colee51666/p/16449666.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
尊重每一个原创,从你我开始!
转载请注明原文链接,如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“👍”哦,博主在此感谢你的支持!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端