springboot mybatis使注解和xml兩種方式同時生效


聲明:該博客參考了: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

網上的解釋大約有如下幾種原因:

  1. xml中的id有重復的
  2. mapper接口文件中出現了接口重載
  3. xml中有些方法的返回值類型沒有指定

以上這些基本都很容易檢查出來,在idea中就會拋出該異常,但是在idea中沒有拋出該異常,那就說明程序的語法,邏輯應該沒問題,那就應該是打完包之后文件路徑變更導致的,我這個就是這種情況,如果是classpath*:/mapper/*.xml這種寫法,在服務器上會當成一個絕對路徑進行尋找,但是實際上這個mapper文件是在resources下放着,打包之后的文件目錄如下:

 正確的寫法應該是:classpath:mapper/*.xml,但是這里仍然有個問題,為什么在idea中沒有拋出這個異常?

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM