记一次简单又令人抓狂的Mybatis异常
老规矩,还是开局先报异常:Invalid bound statement (not found): com.mapper.LoginMapper.login
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.mapper.LoginMapper.login
at org.apache.ibatis.binding.MapperMethod S q l C o m m a n d . < i n i t > ( M a p p e r M e t h o d . j a v a : 227 ) a t o r g . a p a c h e . i b a t i s . b i n d i n g . M a p p e r M e t h o d . < i n i t > ( M a p p e r M e t h o d . j a v a : 49 ) a t o r g . a p a c h e . i b a t i s . b i n d i n g . M a p p e r P r o x y . c a c h e d M a p p e r M e t h o d ( M a p p e r P r o x y . j a v a : 65 ) a t o r g . a p a c h e . i b a t i s . b i n d i n g . M a p p e r P r o x y . i n v o k e ( M a p p e r P r o x y . j a v a : 58 ) a t c o m . s u n . p r o x y . SqlCommand.<init>(MapperMethod.java:227) at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:49) at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:65) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58) at com.sun.proxy. SqlCommand.<init>(MapperMethod.java:227)atorg.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:49)atorg.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:65)atorg.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:58)atcom.sun.proxy.Proxy19.login(Unknown Source)
at com.service.impl.adloginServiceImpl.login(adloginServiceImpl.java:29)
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.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
这个问题还是很好找的,搜索引擎上一找一大堆,基本上最核心的问题就是Mapper.xml有问题,无非就是SQL语句的标签中的id
里面的值没有和Mapper接口的方法对应上**(建议还是复制粘贴为妙)** ;
<select id="" paramType=""></select>
但是看到这里的朋友可能就会心里想要MMP了,就那么简单的几个字母,看了不下十遍,真的没有错,那可能就不是这个原因了。废话不多说,正片开始。
在反复检查之后发现,居然是在applicationContext.xml
里面的配置找到了问题;
<!-- 在配置sqlSessionFactory的时候,使用了批量产生mapper的方式
因此需要配置mapper.xml的位置
-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:com/my/mapper/*.xml"></property>
</bean>
而这次异常正好出现在上面的配置的value="classpath:com/mapper/*.xml"
这里,先看两张图:
-
这是一个maven构建的web项目
- 而在maven项目中,
classpath:
指向的路径是src/resources这个文件夹,所以,使用上面的value写法就会出现问题,导致Spring没办法找到你的Mapper.xml,然后检查配置文件可能一下子没有意识到这个问题
- 而在maven项目中,
最后的解决方案是把**mapper.xml这些mapper文件放在resources文件夹下面即可;
如上图所示:为了规范一点,就另建一个mapper文件夹,当然这里可以按功能划分mapper,总之别放错位置就行了。然后把配置信息修改一下
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>
这样,就可以解决问题了。
最后插点题外话,当初在某站大学学这些东西的时候,up主说为了方便就把mapper.xml放在了接口的文件夹下,java文件与xml文件混着放,这样看方便一点,那个时候也没有多想这个细节点,但是在遇到这个问题的时候,我去求助身边的大佬,他们一上来就说配置文件和java文件要分开放,规范一点。可能我们自己写的普通项目可以随便那么一点点,但是如果是使用maven来构建项目的话,还是要遵循规范好一点,不然某一天忽然因为某个不规范的点引发异常,然后又花费很长的时间去找问题,偷这点懒,得不偿失啊~