錯誤
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();
Map<Object, Object> targetDataSources = 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陳述句了,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/179245.html
標籤:Java
