声明:该博客参考了:https://www.jianshu.com/p/53762ac6d31c
如果上面这个博客中的内容已经解决了你的问题,那就不用往下看了,如何按照上面的配置一直报这个异常:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
请参考如下博客解决:https://blog.csdn.net/softwarehe/article/details/8889206。
如果仍然无法解决,可以尝试下面的方法,这也是我写这篇博客的目的。
一般在项目中都会使用springboot,如果需要使用mysql,一般都会使用阿里的druid数据库连接池,那使用这个连接池的时候,一般都会对druid做一些配置,有的人喜欢在yml中直接配置了,但是有些人可能在程序中搞一个配置类:类似于下面这种(没有全部贴出来,太长):
@Configuration @MapperScan(basePackages = "com.gbgg.graph.goods.mapper", sqlSessionTemplateRef = "sqlSessionTemplate") public class DuridConfig { @Value("${spring.datasource.primary.url:#{null}}") private String dbUrl; @Value("${spring.datasource.primary.username: #{null}}") private String username; @Value("${spring.datasource.primary.password:#{null}}") private String password; @Value("${spring.datasource.primary.driverClassName:#{null}}") private String driverClassName; @Value("${spring.datasource.initialSize:#{null}}") private Integer initialSize; @Value("${spring.datasource.minIdle:#{null}}") private Integer minIdle; @Value("${spring.datasource.maxActive:#{null}}") private Integer maxActive; @Value("${spring.datasource.maxWait:#{null}}") private Integer maxWait; @Value("${spring.datasource.timeBetweenEvictionRunsMillis:#{null}}") private Integer timeBetweenEvictionRunsMillis; @Value("${spring.datasource.minEvictableIdleTimeMillis:#{null}}") private Integer minEvictableIdleTimeMillis; @Value("${spring.datasource.validationQuery:#{null}}") private String validationQuery; @Bean(name = "jdbcTemplate")@Primary public JdbcTemplate jdbcTemplate() { return new JdbcTemplate(dataSource()); } @Bean(name = "transactionManager") @Primary public DataSourceTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } @Bean(name = "sqlSessionFactory") @Primary public SqlSessionFactory setSqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
这个配置类中自己new了一个SqlSessionFactoryBean,这就会导致在yml文件中配置的xml路径根本不起作用,也就是说根本找不到xml文件,所以上面的异常就会一直报。那怎么解决呢?
就是在在即new 的这个SqlSessionFactoryBean中,把xml路径给指定了就可以了,那怎么指定呢,看下面代码:
@Bean(name = "sqlSessionFactory") @Primary public SqlSessionFactory setSqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); configuration.setCallSettersOnNulls(true); bean.setConfiguration(configuration); bean.setVfs(SpringBootVFS.class); //下面这两个就是指定xml路径的 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); bean.setMapperLocations(resolver.getResources("classpath*:/mapper/*.xml")); bean.setDataSource(dataSource); return bean.getObject(); }
好了,以上就是这个问题的解决办法,但有个问题,为什么这里自己new了一个SqlSessionFactoryBean之后,yml文件中配置的就不起作用了呢?这个还在研究,等以后更新,如果有那位大佬知道原理,也麻烦在评论中告知。
------------------------------------------------2019-11-19更新--------------------------------------------------------------
上面的代码在idea中执行时ok的,但是打完包,发到服务器上运行会一直报如下错误:
Mapped Statements collection already contains value for
网上的解释大约有如下几种原因:
- xml中的id有重复的
- mapper接口文件中出现了接口重载
- xml中有些方法的返回值类型没有指定
以上这些基本都很容易检查出来,在idea中就会抛出该异常,但是在idea中没有抛出该异常,那就说明程序的语法,逻辑应该没问题,那就应该是打完包之后文件路径变更导致的,我这个就是这种情况,如果是classpath*:/mapper/*.xml这种写法,在服务器上会当成一个绝对路径进行寻找,但是实际上这个mapper文件是在resources下放着,打包之后的文件目录如下:
正确的写法应该是:classpath:mapper/*.xml,但是这里仍然有个问题,为什么在idea中没有抛出这个异常?