测试一个更新用户密码的mapper方法的时候出现了这个异常:
Caused by: org.apache.ibatis.binding.BindingException: Parameter 'password' not found. Available parameters are [0, 1, param1, param2]
at org.apache.ibatis.binding.MapperMethod$ParamMap.get(MapperMethod.java:186)
at org.apache.ibatis.reflection.wrapper.MapWrapper.get(MapWrapper.java:45)
at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:122)
at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:79)
at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:93)
at org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:64)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:86)
at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:49)
at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117)
at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76)
at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:434)
... 34 more
先看看测试代码
@Update({"update", TABLE_NAME, "set password=#{password} where id=#{id}"})
void setPassword(String password, int id);//mapper方法
userDAO.setPassword("abcd",4);//设置id为4的用户密码
在单个参数的情况下并不会出现找不到参数这个问题,mybatis默认把方法的参数传入sql语句中,如果参数是对象就在对象的属性中查找和#{xxx}中名称相同的属性传入。本来以为这种按照名称匹配的查找方法也适用于方法有多个参数的情况,然而仅仅这样做无法达到这个目的。
下面给出两种比较方便的解决办法。
1. 按照方法的参数顺序,在sql参数中以0、1、2...(参数索引号)代替sql参数的名称。
比如下面的例子#{0}传入方法的第一个参数password,#{1}传入方法第二个参数id。
@Update({"update", TABLE_NAME, "set password=#{0} where id=#{1}"})
void setPassword(String password, int id);
2.引入注解org.apache.ibatis,Param,在方法参数中对每个参数用@Param注解并给出一个和sql语句中需要传入的参数相同的名称,这样就能把方法的参数和sql语句相应参数进行匹配。如下
@Update({"update", TABLE_NAME, "set password=#{password} where id=#{id}"})
void updatePassword(@Param("password") String password, @Param("id") int id);