栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mybatis设置setMapperLocations之后出现BindingException: Invalid bound statement (not found)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mybatis设置setMapperLocations之后出现BindingException: Invalid bound statement (not found)

笔者在开发ssm项目(非springboot)时,笔者使用的是java api方式设置mybatis,没有使用xml,SqlSessionFactory的Bean也是通过java注解方式注册的,也没有使用xml进行配置,如下:

	@Bean
    public SqlSessionFactory sqlSessionFactory(@Autowired DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
        sqlSessionFactoryBean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath" + ":/mapping*.xml
                
                false
            
        

build时才会将xml文件复制到target里。
但是如此配置完之后,返回的Resource数组是没错了,可以解析到mapper.xml,却还是报同样的错误。

二、sqlSessionFactory里是否有你配置的mapperLocations

阅读以下前请先区分sqlSessionFactory与SqlSessionFactoryBean之间的关系
随便建个controller,写一个成员,将sqlSessionFactory注入进去,并在test方法处建断点,并在debug模式运行:
另外类型写DefaultSqlSessionFactory,而不是注册Bean时的SqlSessionFactoryBean,这里还有点意思,可以自己试一下,这篇博文(点击)有解析

@Controller
public class TestController {
    @Resource
    DefaultSqlSessionFactory sqlSessionFactoryBean;
    @Resource
    private BookMapper bookMapper;

    @GetMapping ("/test")
    @ResponseBody
    public String test(Model model) {
        return bookMapper.find("呐喊").toString(); // 此处设断点
    }
}

停在断点处时,查看this.sqlSessionFactory.configuration.mappedStatements:

发现只有两个成员,而且都是insert,而find方法完全没有,说明确实find方法没有被绑定。
之后笔者想到可能是sqlSessionFactoryBean.setMapperLocations方法有问题,

很普通的setter,看不出什么,设个断点,然后在sqlSessionFactoryBean.getObject()看看,毕竟最后用的bean是sqlSessionFactory而不是sqlSessionFactoryBean:

进afterPropertiesSet看看:

几个断言没什么意思,进buildSqlSessionFactory()看看:

找到上图中的设置sqlSessionFactory的mapperLocations的代码,设置断点。
运行程序,发现断点却先停在了上面这张图的地方!!
调用堆栈:

也就是说getObject()方法早于setMapperLocations调用,导致sqlSessionFactoryBean的mapperLocations成员没有赋给sqlSessionFactory。最终sqlSessionFactory的mapperLocations是null!
知道了问题所在之后,把mybatis的bean注册sqlSessionFactory,改为注册sqlSessionFactoryBean,由spring来调用getObject()来获取sqlSessionFactory:(注意对比第一个代码块)

	@Bean
    public SqlSessionFactoryBean sqlSessionFactoryBean(@Autowired DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.getObject().getConfiguration().setMapUnderscoreToCamelCase(true);
        sqlSessionFactoryBean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath" + ":/mapping/*Mapper.xml"));
        sqlSessionFactoryBean.setTypeAliasesPackage("org.j2ee.server.pojo");
        return sqlSessionFactoryBean;
    }

然后就可以成功解决问题了。然而笔者还是不知道为什么getObject()会先于setMapperLocations调用,有知道的朋友欢迎讨论,谢谢!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/683334.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号