SpringBoot多數(shù)據(jù)源讀寫分離的自定義配置問題及解決方法
在開發(fā)中我們有可能會(huì)遇到一個(gè)項(xiàng)目需要配置多個(gè)數(shù)據(jù)源,或者需要讀寫分離的配置,在啟動(dòng)類上貼上@MapperScan注解指定掃描對應(yīng)的mapper.xml文件肯迪那個(gè)是無法滿足了。我們可以通過自定義配置數(shù)據(jù)庫配置類來解決這個(gè)問題,方式有很多,不同的業(yè)務(wù)采用的方式也不同,下面我簡單的介紹我們項(xiàng)目的使用的方法
比如:項(xiàng)目中我需要連接opretion和device這個(gè)兩個(gè)數(shù)據(jù)庫,且需要進(jìn)行讀寫分離,在配置文件中如下:
針對device庫我們先創(chuàng)建一個(gè)數(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類似,都是獲取配置文件中相應(yīng)的配置值,但是@ConfigurationProperties與@Value不同的是,@Value一次只能獲取一個(gè)值,但是@ConfigurationProperties可以獲取多個(gè)值,此處可以將配置文件中的屬性,自動(dòng)封裝到DruidDataSource
的屬性中
配置Sharding數(shù)據(jù)源的Bean,也就是device.read
和device.write
讀寫分離的數(shù)據(jù)源
通過@Qualifier注解來指定我們想要使用 deviceReadDataSource
方法返回的 bean ,即獲取deviceReadDataSource
方法返回DruidDataSource對象,deviceWriteDataSource
同理。
通過LoadBalanceStrategyConfiguration
是實(shí)現(xiàn)我們負(fù)載均衡策略
通過MasterSlaveRuleConfiguration
構(gòu)造方法實(shí)現(xiàn)自定義的負(fù)載均衡算法
@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負(fù)載均衡自動(dòng)配置類 LoadBalanceStrategyConfiguration LoadBalanceStrategyConfiguration loadBalanceStrategyConfiguration = new LoadBalanceStrategyConfiguration("round_robin"); //負(fù)載均衡算法 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); //返回一個(gè)DataSource }
創(chuàng)建返回SqlSessionFactory的Bean
1、創(chuàng)建MybatisSqlSessionFactoryBean
對象配置SqlSessionFactory;
2、創(chuàng)建MybatisConfiguration
對象調(diào)用setMapUnderscoreToCamelCase方法,開啟mapUnderscoreToCamelCase配置駝峰轉(zhuǎn)換
3、創(chuàng)建GlobalConfig
對象出傳入MybatisConfiguration對象設(shè)置關(guān)閉對應(yīng)banner(可以選擇不關(guān),但是利于查看日志和控制臺(tái))
4、通過ResourcePatternResolver
資源模式解析器,配置mapper.xml的文件路徑
@Bean @Primary //在同樣的DataSource中,首先使用被標(biāo)注的SqlSessionFactory public SqlSessionFactory deviceSqlSessionFactory(@Qualifier("deviceShardingDataSource") DataSource shardingDataSource) { MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean(); bean.setDataSource(shardingDataSource); //設(shè)置 MybatisSqlSessionFactory的數(shù)據(jù)源 ? //MyBatis開啟mapUnderscoreToCamelCase配置駝峰轉(zhuǎn)換 MybatisConfiguration configuration = new MybatisConfiguration(); configuration.setMapUnderscoreToCamelCase(true); ? GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration); globalConfig.setBanner(false); //關(guān)閉Mybatis 加載的banner ? bean.setGlobalConfig(globalConfig); bean.setConfiguration(configuration); ? // 添加XML目錄 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //資源模式解析器 try { bean.setMapperLocations(resolver.getResources("classpath:mapper/device/**/*Mapper.xml")); //設(shè)施設(shè)置mapper映射器位置 return bean.getObject(); //返回一個(gè)SqlSessionFactory'po } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } }
題外話:默認(rèn)情況下,
@Autowired
按類型裝配 Spring Bean。如果容器中有多個(gè)相同類型的 bean,則框架將拋出NoUniqueBeanDefinitionException
, 以提示有多個(gè)滿足條件的 bean 進(jìn)行自動(dòng)裝配。程序無法正確做出判斷使用哪一個(gè),所以會(huì)報(bào)錯(cuò),可以使用@Primary和@Qualifier注解類解決這類問題
- 通過將
@Qualifier
注解與我們想要使用的特定 Spring bean 的名稱一起進(jìn)行裝配,Spring 框架就能從多個(gè)相同類型并滿足裝配要求的 bean 中找到我們想要的@Primary
的解,可以用來發(fā)生依賴注入的歧義時(shí)決定要注入哪個(gè) bean。當(dāng)存在多個(gè)相同類型的 bean 時(shí),此注解定義了Bean的首選項(xiàng)。簡單來說就是@Qualifier注解那多個(gè)Bean指定了我要那個(gè)Bean,而@Primary注解表示那個(gè)多個(gè)Bean,先選貼了@Primary注解的Bean
創(chuàng)建SqlSessionTemplate的Bean
方法名要與類名上@MapperScan注解中的sqlSessionTemplateRef屬性值一致;否者無法映射
SqlSessionTemplate是MyBatis-Spring的核心。這個(gè)類負(fù)責(zé)管理MyBatis的SqlSession,調(diào)用MyBatis的SQL方法,翻譯異常。SqlSessionTemplate是線程安全的,可以被多個(gè)DAO所共享使用。
@Bean @Primary public SqlSessionTemplate deviceSqlSessionTemplate(@Qualifier("deviceSqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); }
創(chuàng)建DataSourceTransactionManager 事務(wù)管理器
@Bean @Primary public DataSourceTransactionManager deviceTransactionManager(@Qualifier("deviceShardingDataSource") DataSource shardingDataSource) { return new DataSourceTransactionManager(shardingDataSource); }
到此,我們的配置基本結(jié)束,根據(jù)我們配置的mapper包掃描下創(chuàng)建對應(yīng)的mapper接口,
在resource目錄下根據(jù)我們在配置類中配置的路徑存放即可;
最后
注意:這是一個(gè)數(shù)據(jù)源的案例,當(dāng)是需要配置多個(gè)數(shù)據(jù)源的時(shí)候,流程是一樣的
1.在配置文件中配置數(shù)據(jù)庫連接數(shù)據(jù)
2.創(chuàng)建配置類
3.創(chuàng)建mapper接口和mapper.xml文件
到此這篇關(guān)于SpringBoot多數(shù)據(jù)源讀寫分離的自定義配置問題及解決方法的文章就介紹到這了,更多相關(guān)SpringBoot多數(shù)據(jù)源自定義配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot項(xiàng)目訪問圖片的3種實(shí)現(xiàn)方法(親測可用)
本文主要介紹了springboot項(xiàng)目訪問圖片的3種實(shí)現(xiàn)方法,通過springboot項(xiàng)目訪問除項(xiàng)目根目錄之外的其它目錄的圖片,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09mybatis-plus-boot-starter包與mybatis-plus-generator的沖突解決
本文主要介紹了mybatis-plus-boot-starter包與mybatis-plus-generator的沖突解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10spring boot 注入 property的三種方式(推薦)
這篇文章主要介紹了spring boot 注入 property的三種方式,需要的朋友可以參考下2017-07-07spring boot 添加admin監(jiān)控的方法
這篇文章主要介紹了spring boot 添加admin監(jiān)控的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-02-02SpringBoot Entity中枚舉類型詳細(xì)使用介紹
本文介紹SpringBoot如何在Entity(DAO)中使用枚舉類型。(本文使用MyBatis-Plus)。在實(shí)際開發(fā)中,經(jīng)常會(huì)遇到表示類型或者狀態(tài)的情況,比如:有三種支付方式:微信、支付寶、銀聯(lián)。本文介紹如何這種場景的方案對比,并用實(shí)例來介紹如何用枚舉這種最優(yōu)雅的來表示2022-10-10