When working with MyBatis or MyBatis-Plus in Spring Boot applications, encountering "Invalid bound statement (not found)" exceptions typically indicates that mapper interfaces cannot locate their corresponding XML mapping files. This guide outlines common misconfigurations and their solutions.
Mapper Location Configuration
The primary cause involves incorrect specification of XML resource paths in your application configuration. When mapper XML files reside outside the standard resources directory, you must provide complete classpath patterns:
mybatis-plus:
mapper-locations: classpath*:org/sample/application/repository/**/xml/*Repository.xml
For XML files placed within the resources folder, use relative paths with the classpath wildcard:
mybatis-plus:
mapper-locations: classpath*:mappers/xml/*Mapper.xml
Crucially, verify whether your project uses standard MyBatis or MyBatis-Plus, as their configuration prefixes differ. Using the wrong prefix renders all location settings ineffective:
# For MyBatis:
# mybatis:
# mapper-locations: classpath*:dao/mappings/*.xml
# For MyBatis-Plus:
mybatis-plus:
mapper-locations: classpath*:dao/mappings/*.xml
Intermittent pattern recognition issues sometimes occur with nested directory structures. If classpath*:mapper/system/*.xml works inconsistently, try temporarily simplifying the pattern and restoring it:
mybatis-plus:
mapper-locations:
- classpath*:system/*.xml
- classpath*:org/example/additional/*.xml
Custom SqlSessionFactory Bean Configuration
Manually defining a SqlSessionFactory bean can override MyBatis-Plus auto-configuration, causing YAML settings to be ignored. If you experience binding errors when calling IService methods, inspect your factory bean definition:
@Bean
public SqlSessionFactory sessionFactory(RoutingDataSource dataSource) throws Exception {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
return factoryBean.getObject();
}
This approach bypasses MyBatis-Plus enhancements. Replace SqlSessionFactoryBean with MybatisSqlSessionFactoryBean and explictily configure mapper locations and other settings programmatically:
@Bean
public SqlSessionFactory sessionFactory(RoutingDataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
MybatisConfiguration config = new MybatisConfiguration();
config.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
factoryBean.setConfiguration(config);
factoryBean.setMapperLocations(
new PathMatchingResourcePatternResolver()
.getResources("classpath*:org/sample/app/dao/**/mapping/*.xml")
);
return factoryBean.getObject();
}
Dependency Management
Ensure you import the correct starter dependency. Using the standard MyBatis starter with MyBatis-Plus features creates conflicts with Spring's database mangaement and may cause SqlSessionFactory resolution failures. Include the MyBatis-Plus Boot starter:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
Build Resource Filtering
Maven projects may fail to copy XML files to the target directory. Check your build output for mapper XML files. If absent, configure resource filtering in your pom.xml to include XML resources from both resources and java directories:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.yml</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>