使用mybatis的项目在本地能够正常运行,但当使用maven或Jenkins打包部署到远程服务器上时出现了绑定错误,异常信息为:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.yo.news.user.mapper.UserMapper.getUserByTelPwd
html
首先,给定的异常提示信息并不精准,有多个错误缘由都会抛出该异常。mybatis出现这个问题,一般是由Mapper interface和对应的xml文件的定义对应不上引发的,这时就须要仔细检查对比包名、xml中的namespace、接口中的方法名称等是否对应。我以前就由于称忘记在xml标签的id属性中添加方法名或写错方法名而出现这个错误。java
出现这个错误时,按如下步骤检查通常就会解决问题:
1:检查xml文件所在package名称是否和Mapper interface所在的包名一一对应;
2:检查xml的namespace是否和xml文件的package名称一一对应;
3:检查方法名称是否对应;
4:去除xml文件中的中文注释;
5:随意在xml文件中加一个空格或者空行而后保存。spring
6:若是接口中的返回值List集合(不知道其余集合也是),那么xml里面的配置,尽可能用resultMap(保证resultMap配置正确),不要用resultTypesql
我在项目中遇到的问题可使用第五个解决方法解决:“随意在xml文件中加一个空格或者空行而后保存”,看起来这么怪异的解决方式,其实是触发了IDE的自动编译功能。因为xml文件在编译的时候,不必定总能当即从源目录复制到class文件的编译目录(MyEclipse常常出这个问题),有时候你源目录中的xml文件已经修改好了,而class所在的目录里面仍是旧的。所以真正肯定有效的方式是将正确的xml文件复制到class输出目录。apache
发现了问题就要从根本上解决,而不该该当出现了问题再去解决。我最后发现Jenkins经过maven把项目打成war包,或者Eclipse经过使用maven命令tomcat7:deploy远程自动部署项目打成的war包,war包里面缺乏Mapper对应的xml文件,也就是没有把xml文件打包进去。解决办法是,在pom.xml文件中的build标签中添加以下代码,显示的强制将xml文件打到war包中:tomcat
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
还有种状况会出这个错误,好比配置xml映射文件须要知足特定要求:服务器
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref="dataSource" p:configLocation="classpath:mybatis-config.xml">
<property name="mapperLocations">
<list>
<value>classpath*:mapper/com/xxx/**/*Mapper.xml</value>
<value>classpath*:dao/com/xxx/**/*Mapper.xml</value>
</list>
</property>
</bean>
如上只有Mapper结尾的xml文件才会被Mybatis扫描到,这个时候若是忘记了这个规则,xml使用了其余名称,如xxxDao.xml。这样xml的配置就不会加入到Mybatis存储配置的一个map对象里去,也会出现 Invalid bound statement 的错误。解决方法就是把xml文件更名便可。mybatis
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'status' not found. Available parameters are [param, fromUser, appid, param3, param1, param2] at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:76) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:399) at com.sun.proxy.$Proxy27.update(Unknown Source) at org.mybatis.spring.SqlSessionTemplate.update(SqlSessionTemplate.java:269) at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:55) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53) at com.sun.proxy.$Proxy28.updateDialogByFrom2(Unknown Source) at com.benmu.mts.wx.center.dao.CustomDialogDaoTest.updateDialogByFrom2(CustomDialogDaoTest.java:54) 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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
dao层代码:app
@Repository public interface CustomDialogDao { void updateDialogByFrom2(@Param("param") CustomDialog param, @Param("fromUser") String fromUser, @Param("appid") String appid); }
mapper.xml代码:
maven
<?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.benmu.mts.wx.center.service.dao.CustomDialogDao"> <update id="updateDialogByFrom2" parameterType="com.benmu.mts.wx.center.custom.bean.CustomDialog"> update custom_dialog <set> <if test="status != null"> status = #{status} </if> </set> where 1=1 and appid = #{appid} and fromUser = #{fromUser} </update> </mapper>
解决办法:
<update id="updateDialogByFrom2" > update custom_dialog <set> <if test="param.status != null"> status = #{param.status} </if> </set> where 1=1 and appid = #{appid} and from_user = #{fromUser} </update>
总结:
Dao层已经把CustomDialog定义成了param,若是要使用status,就要调用param这个对象的属性,不然status是找不到的