歡迎您光臨本站 註冊首頁

錯誤

Mybatis-Plus (簡稱MP) 是mybatis的一個增強工具,在mybatis的基礎上只做增強不做改變,簡化了開發效率。其實就是幫我們封裝了一些簡單的curd方法,可以直接調用,不必再重寫這些簡單的sql語句,類似JPA那樣。

前兩天創建了一個新項目,持久層框架用的是mybatis,同時引入mybatis-plus做增強工具,項目啟動後,調用接口卻發現報錯了,報錯的提醒如下:

在這裡插入圖片描述

錯誤的信息顯示的是 “無效的綁定語句“,報錯的地方正是操作sql語句的方法,從網上查了一下答案,該錯誤主要是數據源綁定的配置問題,於是我順騰摸瓜,從配置數據源的地方下手。

查找原因

因為項目是做了多數據源的讀寫分離,所以我把數據源的動態配置整合到了一個類DataSourceConfig中,這是該類的代碼:

  @Configuration  @MapperScan(basePackages = "com.xjt.proxy.mapper", sqlSessionTemplateRef = "sqlTemplate")  public class DataSourceConfig {   /**    * 主庫    */   @Bean   @ConfigurationProperties(prefix = "spring.datasource.master")   public DataSource masterDb() {    return DruidDataSourceBuilder.create().build();   }     /**    * 從庫    */   @Bean   @ConfigurationProperties(prefix = "spring.datasource.slave")   public DataSource slaveDb() {    return DruidDataSourceBuilder.create().build();   }     /**    * 主從動態配置    */   @Bean   public DynamicDataSource dynamicDb(@Qualifier("masterDb") DataSource masterDataSource,            @Autowired(required = false) @Qualifier("slaveDb") DataSource slaveDataSource) {    DynamicDataSource dynamicDataSource = new DynamicDataSource();    MaptargetDataSources = new HashMap<>();    targetDataSources.put(DynamicDataSourceEnum.MASTER.getDataSourceName(), masterDataSource);    if (slaveDataSource != null) {     targetDataSources.put(DynamicDataSourceEnum.SLAVE.getDataSourceName(), slaveDataSource);    }    dynamicDataSource.setTargetDataSources(targetDataSources);    dynamicDataSource.setDefaultTargetDataSource(masterDataSource);    return dynamicDataSource;   }     @Bean   public SqlSessionFactory sessionFactory(@Qualifier("dynamicDb") DataSource dynamicDataSource) throws Exception {    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();    bean.setMapperLocations(      new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*Mapper.xml"));    bean.setDataSource(dynamicDataSource);    return bean.getObject();   }     @Bean   public SqlSessionTemplate sqlTemplate(@Qualifier("sessionFactory") SqlSessionFactory sqlSessionFactory) {    return new SqlSessionTemplate(sqlSessionFactory);   }     @Bean(name = "dataSourceTx")   public DataSourceTransactionManager dataSourceTx(@Qualifier("dynamicDb") DataSource dynamicDataSource) {    DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();    dataSourceTransactionManager.setDataSource(dynamicDataSource);    return dataSourceTransactionManager;   }  }

 

內容沒什麼複雜的,主要是對主從庫的數據源配置映射,以及把數據源注入SqlSessionFactory對象中,如果對該部分代碼或者讀寫分離比較疑惑的話,可以看我之前的文章《讀寫分離很難嗎?springboot結合aop簡單就實現了》

主從庫映射數據源沒什麼異議,想來想去應該是注入那一步有問題,然後就把目光放到了sessionFactory方法上,該方法主要是返回一個SqlSessionFactory對象,該對象是由通過新建一個SqlSessionFactoryBean對象並注入數據源後返回的,問題應該是出在這個SqlSessionFactoryBean類上,後來,經平哥(我旁邊的大佬)提醒後,這裡應該要換成mybatis-plus中另一個Bean工廠類,叫做MybatisSqlSessionFactoryBean,點開該類的源碼,才發現該類正是拷貝了SqlSessionFactoryBean,並且重寫了自己的自定義加載方法buildSqlSessionFactory

在這裡插入圖片描述

跳轉到該方法的源碼中,發現其中有一段代碼比較重要,配置中少了這一步就會注入失敗,

在這裡插入圖片描述

改動

也就是說,注入數據源的地方還需要配置mapper的掃描路徑,如此一來,改動的地方也比較明確了,就是注入數據源的地方把 SqlSessionFactoryBean 改成 MybatisSqlSessionFactoryBean 後,並配置mapper文件對應的路徑,也就是把sessionFactory方法改成如下代碼:

  @Bean   public SqlSessionFactory sessionFactory(@Qualifier("dynamicDb") DataSource dynamicDataSource) throws Exception {    MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();    sqlSessionFactoryBean.setDataSource(dynamicDataSource);    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();  sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:mapper/*Mapper.xml"));    return sqlSessionFactoryBean.getObject();   }

 

這樣一來,再次啟動項目就可以正常操作sql語句了。 


[ljg58026 ] 引入mybatis-plus報 Invalid bound statement錯誤問題的解決方法_java已經有289次圍觀

http://coctec.com/docs/java/show-post-238199.html