聲明:該博客參考了: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中沒有拋出這個異常?