SpringBoot多數(shù)據(jù)源讀寫分離的自定義配置問題及解決方法
在開發(fā)中我們有可能會遇到一個項目需要配置多個數(shù)據(jù)源,或者需要讀寫分離的配置,在啟動類上貼上@MapperScan注解指定掃描對應的mapper.xml文件肯迪那個是無法滿足了。我們可以通過自定義配置數(shù)據(jù)庫配置類來解決這個問題,方式有很多,不同的業(yè)務采用的方式也不同,下面我簡單的介紹我們項目的使用的方法
比如:項目中我需要連接opretion和device這個兩個數(shù)據(jù)庫,且需要進行讀寫分離,在配置文件中如下:

針對device庫我們先創(chuàng)建一個數(shù)據(jù)庫連接配置類
@Configuration
@MapperScan(basePackages = {"com.liuqing.my.repo.device"}, sqlSessionTemplateRef = "deviceSqlSessionTemplate")
public class DeviceDSConfig {
?
@Value("${props.sql.show}") //定義在配置文件中的字段 ture
private String sqlShow;
}@MapperScan
basePackages = {"com.liuqing.my.repo.device"}
指定包掃描
sqlSessionTemplateRef = "deviceSqlSessionTemplate")
指定sqlSessionTemplateRef
在類中添加配置文件中的讀寫數(shù)據(jù)源
@ConfigurationProperties(prefix = "spring.shardingsphere.datasource.device.read")
public DataSource deviceReadDataSource() {
return new DruidDataSource();
}
@Bean
@ConfigurationProperties(prefix = "spring.shardingsphere.datasource.device.write")
public DataSource deviceWriteDataSource() {
return new DruidDataSource();
}@ConfigurationProperties注解的作用和@Value類似,都是獲取配置文件中相應的配置值,但是@ConfigurationProperties與@Value不同的是,@Value一次只能獲取一個值,但是@ConfigurationProperties可以獲取多個值,此處可以將配置文件中的屬性,自動封裝到DruidDataSource的屬性中
配置Sharding數(shù)據(jù)源的Bean,也就是device.read和device.write讀寫分離的數(shù)據(jù)源
通過@Qualifier注解來指定我們想要使用 deviceReadDataSource 方法返回的 bean ,即獲取deviceReadDataSource方法返回DruidDataSource對象,deviceWriteDataSource同理。
通過LoadBalanceStrategyConfiguration是實現(xiàn)我們負載均衡策略
通過MasterSlaveRuleConfiguration構造方法實現(xiàn)自定義的負載均衡算法
@Bean
public DataSource deviceShardingDataSource(@Qualifier("deviceReadDataSource") DataSource readDataSource, //指定使用deviceReadDataSource的Bean返回的readDataSource對象
@Qualifier("deviceWriteDataSource") DataSource writeDataSource) throws SQLException {
Map<String, DataSource> dataSourceMap = new HashMap<>();
?
dataSourceMap.put("device-read", readDataSource);
dataSourceMap.put("device-write", writeDataSource);
?
//Spring負載均衡自動配置類 LoadBalanceStrategyConfiguration
LoadBalanceStrategyConfiguration loadBalanceStrategyConfiguration = new LoadBalanceStrategyConfiguration("round_robin");
//負載均衡算法
MasterSlaveRuleConfiguration masterSlaveRuleConfig =
new MasterSlaveRuleConfiguration(
"device_read_write",
"device-write",
Lists.newArrayList("device-read"),
loadBalanceStrategyConfiguration);
?
Properties properties = new Properties();
properties.setProperty("sql.show", sqlShow);
?
return MasterSlaveDataSourceFactory.createDataSource(dataSourceMap, masterSlaveRuleConfig, properties); //返回一個DataSource
}創(chuàng)建返回SqlSessionFactory的Bean
1、創(chuàng)建MybatisSqlSessionFactoryBean對象配置SqlSessionFactory;
2、創(chuàng)建MybatisConfiguration對象調用setMapUnderscoreToCamelCase方法,開啟mapUnderscoreToCamelCase配置駝峰轉換
3、創(chuàng)建GlobalConfig對象出傳入MybatisConfiguration對象設置關閉對應banner(可以選擇不關,但是利于查看日志和控制臺)
4、通過ResourcePatternResolver資源模式解析器,配置mapper.xml的文件路徑
@Bean
@Primary //在同樣的DataSource中,首先使用被標注的SqlSessionFactory
public SqlSessionFactory deviceSqlSessionFactory(@Qualifier("deviceShardingDataSource") DataSource shardingDataSource) {
MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
bean.setDataSource(shardingDataSource); //設置 MybatisSqlSessionFactory的數(shù)據(jù)源
?
//MyBatis開啟mapUnderscoreToCamelCase配置駝峰轉換
MybatisConfiguration configuration = new MybatisConfiguration();
configuration.setMapUnderscoreToCamelCase(true);
?
GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration);
globalConfig.setBanner(false); //關閉Mybatis 加載的banner
?
bean.setGlobalConfig(globalConfig);
bean.setConfiguration(configuration);
?
// 添加XML目錄
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //資源模式解析器
try {
bean.setMapperLocations(resolver.getResources("classpath:mapper/device/**/*Mapper.xml")); //設施設置mapper映射器位置
return bean.getObject(); //返回一個SqlSessionFactory'po
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}題外話:默認情況下,
@Autowired按類型裝配 Spring Bean。如果容器中有多個相同類型的 bean,則框架將拋出NoUniqueBeanDefinitionException, 以提示有多個滿足條件的 bean 進行自動裝配。程序無法正確做出判斷使用哪一個,所以會報錯,可以使用@Primary和@Qualifier注解類解決這類問題
- 通過將
@Qualifier注解與我們想要使用的特定 Spring bean 的名稱一起進行裝配,Spring 框架就能從多個相同類型并滿足裝配要求的 bean 中找到我們想要的@Primary的解,可以用來發(fā)生依賴注入的歧義時決定要注入哪個 bean。當存在多個相同類型的 bean 時,此注解定義了Bean的首選項。簡單來說就是@Qualifier注解那多個Bean指定了我要那個Bean,而@Primary注解表示那個多個Bean,先選貼了@Primary注解的Bean
創(chuàng)建SqlSessionTemplate的Bean
方法名要與類名上@MapperScan注解中的sqlSessionTemplateRef屬性值一致;否者無法映射
SqlSessionTemplate是MyBatis-Spring的核心。這個類負責管理MyBatis的SqlSession,調用MyBatis的SQL方法,翻譯異常。SqlSessionTemplate是線程安全的,可以被多個DAO所共享使用。
@Bean
@Primary
public SqlSessionTemplate deviceSqlSessionTemplate(@Qualifier("deviceSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}創(chuàng)建DataSourceTransactionManager 事務管理器
@Bean
@Primary
public DataSourceTransactionManager deviceTransactionManager(@Qualifier("deviceShardingDataSource") DataSource shardingDataSource) {
return new DataSourceTransactionManager(shardingDataSource);
}到此,我們的配置基本結束,根據(jù)我們配置的mapper包掃描下創(chuàng)建對應的mapper接口,

在resource目錄下根據(jù)我們在配置類中配置的路徑存放即可;

最后
注意:這是一個數(shù)據(jù)源的案例,當是需要配置多個數(shù)據(jù)源的時候,流程是一樣的
1.在配置文件中配置數(shù)據(jù)庫連接數(shù)據(jù)
2.創(chuàng)建配置類
3.創(chuàng)建mapper接口和mapper.xml文件
到此這篇關于SpringBoot多數(shù)據(jù)源讀寫分離的自定義配置問題及解決方法的文章就介紹到這了,更多相關SpringBoot多數(shù)據(jù)源自定義配置內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解javaweb中jstl如何循環(huán)List中的Map數(shù)據(jù)
這篇文章主要介紹了詳解javaweb中jstl如何循環(huán)List中的Map數(shù)據(jù)的相關資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內容,需要的朋友可以參考下2017-10-10
SpringBoot實現(xiàn)設置動態(tài)定時任務的方法詳解
這篇文章主要介紹了SpringBoot實現(xiàn)設置動態(tài)定時任務的方法詳解,SpringBoot是一個快速開發(fā)的Java框架,而動態(tài)定時任務是指可以在運行時動態(tài)添加、修改和刪除定時任務的功能,需要的朋友可以參考下2023-10-10
SpringBoot注解@EnableScheduling定時任務詳細解析
這篇文章主要介紹了SpringBoot注解@EnableScheduling定時任務詳細解析,@EnableScheduling 開啟對定時任務的支持,啟動類里面使用@EnableScheduling 注解開啟功能,自動掃描,需要的朋友可以參考下2024-01-01

