在 mybatis 开发中,若遇到 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 的异常信息,表示我们的 mybatis dao 相关接口与 mapper 的配置文件之间的映射绑定关系出现了问题。
配置问题
mapper location 没有配置
以 spring boot yml 配置为例,未在 application.yml 上进行如下配置:
mybatis:
mapper-locations: classpath*:demo/mapper/*.xml
以 spring boot 基于 java 配置为例,如下:
package demo.config;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = {"demo.mapperWrong"}, sqlSessionTemplateRef = "testSqlSessionTemplate")
public class DBConfig {
@Bean(name = "testDataSource")
@ConfigurationProperties("datasource.test")
public DataSource dataSource() {
HikariDataSource hikariDataSource = (HikariDataSource) DataSourceBuilder.create().build();
return hikariDataSource;
}
@Bean(name = "testSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
try {
// 没有如下配置,且 @MapperScan 的 basePackages 未为 xml 和 mapper(dao)所在路径时
// sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources("classpath*:demo/mapper/*.xml"));
return sqlSessionFactoryBean.getObject();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
@Bean(name = "testDataSourceTransactionManager")
public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("testDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "testSqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
mapper scan 配置问题
mapper(或者 dao)和 mybatis 对应 bean 的 xml 配置路径不对。
最典型的是,配置路径名称中包含的点作为包名称的一部分,而不是包路径的分割符,如下:
DemoMapper 放在了 package demo.mapper
路径下,而对应的 xml 文件放在了 resources
下面的 demo.mapper
名下(IDE 的操作不当,这时要细看当前 demo.mapper
是路径名称还是类似包路径的 demo/mapper
),如果此时的 mapper location 配置是 classpath*:demo/mapper/*.xml
就会报未绑定的错误;解决方法是修改 xml 配置的路径(注意 IDE 操作),或者直接可以把配置改成 classpath*:demo.mapper/*.xml
。
名称问题
bean xml 文件的 sql 相关的方法名不匹配
bean xml 中的 sql 相关方法名不匹配,如下:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="demo.mapper.DemoMapper">
<resultMap id="baseResultMap" type="demo.entity.Test">
<id column="id" property="id"/>
<result column="rich_text_html" property="richTextHtml"/>
</resultMap>
<sql id="baseColumnList">
id, rich_text_html
</sql>
<sql id="tableName">
knowledge
</sql>
<select id="selLis" resultMap="baseResultMap">
select
<include refid="baseColumnList"/>
from
<include refid="tableName"/>
<where>
1 = 1
</where>
</select>
</mapper>
package demo.mapper;
import demo.entity.Test;
import java.util.List;
public interface DemoMapper {
List<Test> selList();
}
mapper(或者 dao)里的 selList
方法名和 xml 配置的 selLis
不匹配,针对此问题除了错误发生时,异常报出之外,还可以通过 IDE 中 mybatis 相关插件可以在编码阶段得到错误的提示。