前言
这是自己在学MyBatis框架,做一个根据条件查询学生信息实现分页的demo时遇到的bug。
一、报错
###Error querying database.
Cause: org.apache.ibatis.binding.BindingException: Parameter ‘name’ not found. Available parameters are [student, page, param1, param2]
报错内容说无法获取名为’name’的元素,可获取的元素是[student, page, param1, param2]
二、分析
报错提示很明显,就是你不能获取到’name’这个元素,你可以获取到的元素只有[student, page, param1, param2]。
接口代码:
// 根据条件查询学生的信息,实现分页
List<Student> selectPage(@Param("student") Student student, @Param("page") PageUtil page);
正确的映射代码:
<select id="selectPage" resultMap="baseMap">
select <include refid="Base_Column_List"></include> from student
<where>
<if test="student.name != null">
name like "%"#{student.name}"%"
</if>
<if test="student.sex != null">
and sex = #{student.sex}
</if>
<if test="student.birthday != null">
and birthday = #{student.birthday}
</if>
<if test="student.age != null and student.age > 0">
and age = #{student.age}
</if>
<if test="student.classid != null and student.classid > 0">
and classid = #{student.classid}
</if>
</where>
limit #{page.start}, #{page.end}
</select>
开始时我有两处错误,一处是test里面的属性获取错了,比如: test="student.name != null"
但我开始写的是 test="name != null"
;而且我的ognl表达式也获取错了,比如 name like "%"#{student.name}"%"
但我开始写的是 name like "%"#{name}"%"
。第二个错误是比较容易找到的,因为自己为参数添加了@param标签,所以在获取参数时,应该通过@param标签里的key值,来调用对象的属性的方式来获取到某个属性,就像这样 #{student.name}
。
但解决了第二个错误后,仍然报这个错误,开始还没有意识到自己犯了两处错误。这就导致我怀疑自己的修改是否是正确的。这也导致我让第一个错误困扰了我好长时间,主要原因是刚学习这块知识,对语法什么的都不太熟练。
那我是怎么分析解决的呢?首先,根据报错,它告诉我找不到name属性,那我就要明确到底哪里用到了name属性,一共有三处,test里面一处,like前面一处,like后面一处。然后我开始分析这三处name各起什么作用。like前面的name是数据库字段,like后面的name是获取到的Java参数,而且用到了@param标签,证明自己的修改是正确的。接下来就将焦点移动到了test里面的name。我突然意识到test里面的name属性也是参数,是对参数要做的判断,这使我豁然开朗。但标签元素里的参数不需要用ognl表达式,所以直接用key调用属性即可。
就是这样一个小错误困扰了自己一下午。但最重要的我想不是为这个bug耗费了很多无效的时间然后把这个bug给解决了,而是遇到问题后,分析问题解决问题的能力才是自己最大的收获。
三、解决办法
以后遇到什么参数无法获取,可获取的参数是什么什么的报错的时候。首先要分析:
①哪里用到了这个参数
②这个参数在程序中到底起的是什么作用
③相关的语法是什么
明确这三个问题后,都排查过后,相信bug也应该解决了。
四、知识点补充——MyBatis框架中参数获取的语法
1. 只有一个参数
- 如果是 基本数据类型或其封装类型或String类型
默认可直接通过参数名直接获取 - 如果是对象
默认可直接通过属性名来获取
2. 两个参数及以上
- 必须使用@param(“key”)注解里的key来获取。如果是对象,通过key.属性名来获取对应的属性。
- 当然一个参数的情况下,也是可以使用@param()注解的。
总结
以上就是自己对于参数无法获取这个bug的参数总结,通过学习让自己明确了如何分析解决这类参数没有获取到的bug,以及加深了对获取参数的语法的理解。