转载

使用mybatis3自作聪明的后果

本来想写个seata的使用方法的,结果出师不利啊!

不多说 先抛出错误:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.seata.service.AreaService.getAll
复制代码

看到这个错误的第一反应是dao层的mapper对应XML的‘namespace’(命名空间)错了。

然后对了半天也mo问题,使用IDEA的mybatis插件也能跳转。

分析

感觉不对啊,不应该出问题的,再回去看错误日志

使用mybatis3自作聪明的后果

发现问题了,错误发生在controller层

就开始奇怪了为什么Controller层会发生找不到getAll()方法,这个Bean是Spring注入的,中间还隔了一个Service层,再仔细一看看到了这行错误日志就有头绪了:

org.apache.ibatis.binding.BindingException:
复制代码

Controller层调用Service层抛出了mybatis的异常,这个时候我就有点疑问。

纳尼~,这不是很奇怪吗,我用的是Spring的注入那也应该报错的是Spring抛出的异常!!!

接着我就在自动注入的地方下了个断点,是不是注入有问题

使用mybatis3自作聪明的后果

为什么会是mybatis的代理类呢???

使用mybatis3自作聪明的后果

我这里和mybatis没一毛钱关系啊

使用mybatis3自作聪明的后果

为什么mybatis会加载Service的Bean??

这时候机智的小伙伴应该想到了为什么,现在掏出本场Bug的幕后黑手:point_down:

使用mybatis3自作聪明的后果

就是这个注解和注解里面的路径导致的,找到幕后黑手我们就来简单分析一波

我先去mybatis3的官网找来下@MapperScan注解的功能

使用mybatis3自作聪明的后果

@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你当然找不到

本来想着扫描范围大点我能省点事,把自己坑的嘞。

最后有个彩蛋

使用mybatis3自作聪明的后果

看到了resourecs下新建了2个一模一样的文件居然不自动重叠?

这是访达里的目录结构:

使用mybatis3自作聪明的后果

记得在resourecs下千万不要这么兴建目录

使用mybatis3自作聪明的后果

不然maven打包后的结构就只这样的,这样运行代码也会抛出 Invalid bound statement (not found)

使用mybatis3自作聪明的后果

目录写成这样就行了

使用mybatis3自作聪明的后果
原文  https://juejin.im/post/5d557bd1518825265168b614
正文到此结束
Loading...