目录
所以,很关键就是可以得知,这次的报错原因是可以排除掉以下几种情况的:
1、XxxMapper接口类(Dao层)和 xml 文件映射出错(如:xml 文件中配置的 未指定到准确的XxxMapper接口类所在路径)。
2、指示 XxxMapper.xml 映射文件(mybatis文件)的存放路径
问题现象:
今天在使用 MybatisPlus 的过程中,启动项目后,出现了如下报错:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com...XxxMapper.insert
问题分析:
从报错日志来看,是因为
注入失败,导致了无效的绑定语句(找不到bean对象)!!!
这里报错的关键在于:方法名。
和以往遇到的 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com...XxxMapper 报错的区别在于:
1、现在遇到的报错中是定位到了 insert 这个 方法 中!
2、而以往的报错,是定位在 XxxMapper 这个 类 上!
所以,很关键就是可以得知,这次的报错原因是可以排除掉以下几种情况的:
1、XxxMapper接口类(Dao层)和 xml 文件映射出错(如:xml 文件中配置的 <mapper namespace="com...XxxMapper"> 未指定到准确的XxxMapper接口类所在路径)。
2、XxxMapper接口类(Dao层)或 xml 文件 未被扫描到(如:@MapperScan 配置有误或application文件未指定 mapper-locations 路径)
3、XxxMapper接口类注入失败(如:XxxMapper接口类未添加@Component 或 @Mapper 之类的注解,或注入时未添加@Autowired 或 @Resource 之类的注解)
言归正传,由于不是 XxxMapper接口类 的绑定有问题,所以只能从报错位置入手:
根据报错日志,找到图片记录的报错类的第68行:
可以看到这里是调用了一个 save方法,继续追踪可以发现这个save方法是来源于mybatisplus 的 IService接口类:
从源代码可知,这个 save 方法的底层是调用了mybatisplus定义的 baseMapper(基础Dao层)的 insert 方法,由此可知,报错原因就是因为:
mybatisplus 的 baseMapper 注入失败了!!!导致调用该 (基础Dao层)的实例对象的 insert 方法时,无法找到 bean对象!!!
既然知道了原因,那解决方法就呼之欲出了!
解决方法:
1、修改项目中数据源的config类配置
适用于项目中存在自定义的数据源的config配置类的情况下,常用于项目中存在多数据源的情况(注:并不是所有的mybatisplus项目都会自定义数据源的config配置类)
数据源配置类中肯定会用到 mybatisplus配置,如我的项目中有个 RunDataSourceConfig 配置类,此时我们要做的就是保证配置类的写法符合mybatisplus的规范!!!
在 mybatis 中SqlSessionFactory的初始化方法如下:
//指定 xml映射文件所在路径
static final String MAPPER_LOCATION = "classpath:mybatis/mapper/run/*.xml";
//指定 mybatis-config.xml配置文件所在路径
static final String ChangeDataSourceConfig.MYBATIS_CONFIG_LOCATION = "/mybatis/mybatis-config.xml";
@Bean(name = "runSqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("runDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
//加载mybatis.xml映射文件
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
//读取mybatis-config.xml配置文件,没有的话可以去掉
ClassPathResource classPathResource = new ClassPathResource(ChangeDataSourceConfig.MYBATIS_CONFIG_LOCATION);
bean.setConfigLocation(classPathResource);
//加载 DataSource 数据源对象
bean.setDataSource(dataSource);
return bean.getObject();
}
而在 mybatis 作了 mybatisplus 升级后,该方法写法是需要修改的;用 MybatisSqlSessionFactoryBean 替换 SqlSessionFactoryBean,如下:
//指定 xml映射文件所在路径
static final String MAPPER_LOCATION = "classpath:mybatis/mapper/run/*.xml";
//指定 mybatis-config.xml配置文件所在路径
static final String ChangeDataSourceConfig.MYBATIS_CONFIG_LOCATION = "/mybatis/mybatis-config.xml";
@Bean(name = "runSqlSessionFactory")
public SqlSessionFactory testSqlSessionFactory(@Qualifier("runDataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
//加载mybatis.xml映射文件
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCATION));
//读取mybatis-config.xml配置文件,没有的话可以去掉
ClassPathResource classPathResource = new ClassPathResource(ChangeDataSourceConfig.MYBATIS_CONFIG_LOCATION);
bean.setConfigLocation(classPathResource);
//加载 DataSource 数据源对象
bean.setDataSource(dataSource);
return bean.getObject();
}
注意:
1. 如果存在自定义配置类,则该类中有和数据源相关的配置,需要保证写法符合mybatisplus的规范;
2. 如果不存在1. 中的情况,则springboot 项目会使用默认的 mybatisplus 配置,因此也就不需要关注写法规范的问题。
此时重新启动项目即可解决报错,启动成功 :
如果能正常启动的话,那就可以忽略下面的第2步了。
拓展:
第2步说的其实并不是本文章所述的报错,正如文章开头所言,以下解法其实是适用于 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com...XxxMapper 的报错,而该报错和本文章所述的报错的区别上面已经提过了,这里不再赘述,主要是为了给遇到该报错的小伙伴提供一种解决思路:
2、修改项目中使用的 application 配置文件
1、适用于项目中未创建过自定义的数据源的config配置类
2、适用于项目中存在配置类但该类中不存在任何关于数据源的配置
以上情况,常用于项目中只存在单数据源的情况。
此时项目会使用 springboot 和 mybatisplus 的默认配置,但也需要做如下配置:
1、指示 Xxxmapper(Dao层)的存放目录
如果是以下情况:
项目中未创建过自定义的数据源的config配置类
可以在项目的启动类上添加 @MapperScan 注解,如:
如果是符合以下情况:
项目中存在配置类但该类中不存在任何关于数据源和mybatis文件的配置
可以在 MybatisConfig类上添加 @MapperScan 注解,如:
当然也可以在项目的启动类上添加该注解,一样有效。
2、指示 XxxMapper.xml 映射文件(mybatis文件)的存放路径
由于不存在配置类,或配置类不存在数据源和mybatis文件相关的配置,我们可以在项目的 application 配置文件上做文章,添加 mybatis-plus.mapper-locations 配置,如:
对应如下路径: