本来想写个seata的使用方法的,结果出师不利啊!
不多说 先抛出错误:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.seata.service.AreaService.getAll 复制代码
看到这个错误的第一反应是dao层的mapper对应XML的‘namespace’(命名空间)错了。
然后对了半天也mo问题,使用IDEA的mybatis插件也能跳转。
感觉不对啊,不应该出问题的,再回去看错误日志
发现问题了,错误发生在controller层
就开始奇怪了为什么Controller层会发生找不到getAll()方法,这个Bean是Spring注入的,中间还隔了一个Service层,再仔细一看看到了这行错误日志就有头绪了:
org.apache.ibatis.binding.BindingException: 复制代码
Controller层调用Service层抛出了mybatis的异常,这个时候我就有点疑问。
纳尼~,这不是很奇怪吗,我用的是Spring的注入那也应该报错的是Spring抛出的异常!!!
接着我就在自动注入的地方下了个断点,是不是注入有问题
为什么会是mybatis的代理类呢???
我这里和mybatis没一毛钱关系啊
为什么mybatis会加载Service的Bean??
这时候机智的小伙伴应该想到了为什么,现在掏出本场Bug的幕后黑手:point_down:
就是这个注解和注解里面的路径导致的,找到幕后黑手我们就来简单分析一波
我先去mybatis3的官网找来下@MapperScan注解的功能
@Configuration这个注解大部分人都用过吧也是一个注册SpringBean的注解(现在一部分人应该知道为什么会注入的时候发生意料之外的Bean的吧)
@MapperScan注解最终被mybatis-spring这个jar的MapperScannerRegistrar类实现里面有
void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry, String beanName) 复制代码
这个方法用来注册Bean,里面的具体方法我就不细扣了感兴趣的自己去找吧,项目地址在 这里
@MapperScan(basePackages = "com.example.seata.dao") 复制代码
在启动类的自动扫描后具体到dao就解决问题了
总的来说就是 MapperScanner做扫描的时候,把Service也扫描进去了然后注入的,这个时候我们使用的getAll()的方法就会报找不到映射文件的错误
<mapper namespace="com.example.seata.dao.AreaMapper"> 复制代码
因为本来就不是你丫的mapper你当然找不到
本来想着扫描范围大点我能省点事,把自己坑的嘞。
看到了resourecs下新建了2个一模一样的文件居然不自动重叠?
这是访达里的目录结构:
记得在resourecs下千万不要这么兴建目录
不然maven打包后的结构就只这样的,这样运行代码也会抛出 Invalid bound statement (not found)
目录写成这样就行了