SpringBoot集成Mybatis實現(xiàn)對多數(shù)據(jù)源訪問原理
注意?:SpringBoot實際上連接多數(shù)據(jù)源的方式有很多種,也有很多成熟的技術(shù)選型,本文所提供的思路僅是為了幫助讀者加深SqlSessionFactoryBean的理解和使用。
什么是多數(shù)據(jù)源
在現(xiàn)代軟件架構(gòu)中,多數(shù)據(jù)源指的是應(yīng)用程序配置和連接到多個數(shù)據(jù)庫實例的能力。這種架構(gòu)允許應(yīng)用程序根據(jù)不同的業(yè)務(wù)需求、數(shù)據(jù)類型或性能要求,與多個獨立的數(shù)據(jù)庫環(huán)境交互。在實現(xiàn)上,每個數(shù)據(jù)源都有自己的連接池、事務(wù)管理和數(shù)據(jù)訪問對象。
上述專業(yè)定義可能有些晦澀難懂,其實你完全可以將多數(shù)據(jù)源的概念可以類比于一個大型學(xué)校里有多個圖書館和圖書管理員的情況。每個圖書館(數(shù)據(jù)源)由不同的圖書管理員(數(shù)據(jù)庫管理系統(tǒng))負責(zé),管理著特定類型的書籍(數(shù)據(jù))。
比如,一個圖書館可能專注于科學(xué)書籍,而另一個專門存放文學(xué)作品。這樣的安排不僅提高了查找信息的效率——因為每個管理員都對自己的領(lǐng)域非常了解,同時還增強了安全性——因為可以為不同類型的數(shù)據(jù)設(shè)置不同級別的保護。
隨著學(xué)校(業(yè)務(wù))的發(fā)展,可能需要新的圖書館來容納更多的書籍(數(shù)據(jù)),這時多圖書館的布局就顯得尤為重要??偠灾?,多數(shù)據(jù)源在軟件應(yīng)用中的作用就像這些圖書館和圖書管理員一樣,確保數(shù)據(jù)的有效管理、安全和高效訪問。"

如上這張圖就反映了應(yīng)用中多數(shù)據(jù)源和單數(shù)據(jù)源之間的區(qū)別。接下來,我們就來分析在SpringBoot應(yīng)用中,如何通過配置SqlSessionFactoryBean來實現(xiàn)多數(shù)據(jù)源的連接。
環(huán)境搭建
工欲善其事必先利其器,開始動手之前我們先來對構(gòu)建案例所需的環(huán)境進行一個簡單的介紹。后續(xù)案例所需的關(guān)鍵依賴如下:
SpringBoot的構(gòu)建web應(yīng)用的關(guān)鍵依賴:Spring-boot-starter-webSpringBoot整合Mybatis的關(guān)鍵Starter:mybatis-spring-boot-startermysql的jdbc連接依賴:mysql-connector-java- 數(shù)據(jù)連接池
druid:druid-spring-boot-starter
項目整體結(jié)構(gòu)如下:

dao1:數(shù)據(jù)源1所對應(yīng)的數(shù)據(jù)Mapper接口;dao2:數(shù)據(jù)源2所對應(yīng)的數(shù)據(jù)Mapper接口;config: 通過@Configuration標注的配置類信息。
除此之外,我們還需要準備兩個數(shù)據(jù)源信息,在此筆者準了如下所示的test_db和test_db1兩個數(shù)據(jù)庫,其內(nèi)部均有一張t_user的數(shù)據(jù)表。

t_user數(shù)據(jù)表包含name和type兩個字段信息。
實戰(zhàn)雙數(shù)據(jù)源配置
在開始之前,我們先來簡單回顧下SpringBoot集成Mybatis時在連接單數(shù)據(jù)源時是如何進行配置的:
spring:
datasource:
username: root
password: root
# allowMultiQueries表示支持執(zhí)行;間隔的多個sql nullCatalogMeansCurrent=true返回指定庫涉及的表
jdbc-url: jdbc:mysql://127.0.0.1:3306/test_db?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&tcpKeepAlive=true&autoReconnect=true&allowMultiQueries=true&nullCatalogMeansCurrent=true
driver-class-name: com.mysql.cj.jdbc.Driver
# 使用的連接池的類型
type: com.alibaba.druid.pool.DruidDataSource
在上述配置文件中,我們主要配置了如下內(nèi)容:
- 數(shù)據(jù)庫URL (
spring.datasource.url): 這是數(shù)據(jù)庫服務(wù)器的地址和數(shù)據(jù)庫名。它通常包含協(xié)議(例如jdbc:mysql:)、主機地址、端口號(對于MySQL,默認是3306),以及要連接的數(shù)據(jù)庫名。例如:jdbc:mysql://localhost:3306/test_db - 用戶名 (
spring.datasource.username): 用于連接數(shù)據(jù)庫的用戶名。 - 密碼 (
spring.datasource.password): 用于連接數(shù)據(jù)庫的密碼。 - 驅(qū)動類名 (
spring.datasource.driver-class-name): 這是JDBC驅(qū)動的完整類名,它用于告訴Spring Boot應(yīng)用程序使用哪種數(shù)據(jù)庫。例如,對于MySQL,通常是com.mysql.cj.jdbc.Driver。
當我們配置多數(shù)據(jù)源時,配置文件需要做如下的修改:
spring:
# 數(shù)據(jù)源1
primary:
username: root
password: root
jdbc-url: jdbc:mysql://127.0.0.1:3306/test_db?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&tcpKeepAlive=true&autoReconnect=true&allowMultiQueries=true&nullCatalogMeansCurrent=true
driver-class-name: com.mysql.cj.jdbc.Driver
# 使用的連接池的類型
type: com.alibaba.druid.pool.DruidDataSource
# 數(shù)據(jù)源2
slave:
username: root
password: root
jdbc-url: jdbc:mysql://127.0.0.1:3306/test_db1?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&tcpKeepAlive=true&autoReconnect=true&allowMultiQueries=true&nullCatalogMeansCurrent=true
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
此時,我們將之前配置文件中datasource改為了primary 和 slave,這樣SpringBoot 就不再會為我們設(shè)定默認數(shù)據(jù)庫。與此同時,我們將url改為了jdbc-url。這是因為 當只有單個數(shù)據(jù)源時,SpringBoot 會默認將url 映射為 jdbc-url 進行映射,進而保證我們獲得數(shù)據(jù)源的成功注入。
此外,由于我們不再使用SpringBoot的默認配置來加載數(shù)據(jù)源,所以需要手動設(shè)置的數(shù)據(jù)源的連接地址,如果不進行修改,則會導(dǎo)致項目無法啟動,進而出現(xiàn) jdbcUrl is required with driverClassName 的異常。
處理好配置文件后,我們需要構(gòu)建出DataSource、SqlSessionFactory從而實現(xiàn)對SqlSessionFactoryBean的定制化配置,其具體配置如下:
@Configuration
@MapperScan(basePackages = "com.example.dao1", sqlSessionFactoryRef = "sqlSessionFactory1")
public class DataSource1Config {
@Bean
@ConfigurationProperties(prefix = "spring.primary")
public DataSource dataSourcePrimary() {
return DataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory sqlSessionFactory1() throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSourcePrimary());
String locationPattern = "classpath*:/mapperPrimary/*.xml";
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
return sessionFactoryBean.getObject();
}
@Bean(name = "sqlSessionTemplate1")
public SqlSessionTemplate sqlSessionTemplate1(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
當我們期待使用Mybatis操作多數(shù)據(jù)源時,對于不同的數(shù)據(jù)源,我們都需要定義不同的Mapper接口和XML映射文件,以確保最終生成的Mapper實現(xiàn)類可以操縱不同的數(shù)據(jù)源信息。所以,其中的dataSourcePrimary就是為了加載dataSourcePrimary指定的數(shù)據(jù)源信息,確保構(gòu)建的數(shù)據(jù)源最終連接到Primary中指定的數(shù)據(jù)庫信息。而在sqlSessionFactory的構(gòu)建中,則主要通過SqlSessionFactoryBean來構(gòu)建出一個SqlSessionFactory并注入容器,而在這一過程中需要設(shè)定Mapper接口所對應(yīng)的配置文件。
slave的配置可參考DataSource1Config進行配置,在此便不進行贅述。接下來,我們來看下最終的效果:
@RestController
@RequestMapping("/data")
@Slf4j
public class DataSourceController {
@Autowired
private User1Mapper userMapper;
@Autowired
private User2Mapper user2Mapper;
@GetMapping("/get-user1/{name}")
public User getUserFromTestDb(@PathVariable("name") String userName) {
return userMapper.selectUser(userName);
}
@GetMapping("/get-user2/{name}")
public User getUserFromTestDb2(@PathVariable("name") String userName) {
return user2Mapper.selectUser(userName);
}
}
getUserFromTestDb用于從數(shù)據(jù)源test_db獲取數(shù)據(jù)getUserFromTestDb2用于從數(shù)據(jù)源test_db1獲取數(shù)據(jù)
最終效果如下:
訪問數(shù)據(jù)源1

訪問數(shù)據(jù)源2

總結(jié)
接下來,我們對上述程序用到的組件進行一個簡要的總結(jié)和回顧
數(shù)據(jù)源(
DataSource)。數(shù)據(jù)源是數(shù)據(jù)庫連接的工廠。在Spring中,DataSource對象負責(zé)提供數(shù)據(jù)庫連接。當配置多個數(shù)據(jù)源時,每個數(shù)據(jù)源都對應(yīng)不同的數(shù)據(jù)庫連接信息。例如,一個數(shù)據(jù)源可能連接到數(shù)據(jù)庫test_db,而另一個連接到數(shù)據(jù)庫test_db1。Mybatis的SqlSessionFactory。SqlSessionFactory是Mybatis中的一個核心組件,它負責(zé)創(chuàng)建SqlSession。SqlSession提供了執(zhí)行SQL命令、獲取映射器和管理事務(wù)的方法。在配置多個數(shù)據(jù)源的情況下,每個數(shù)據(jù)源都需要有對應(yīng)的SqlSessionFactory,以確保SQL操作能夠針對正確的數(shù)據(jù)庫執(zhí)行。@MapperScan注解的使用。該注解用于指定哪些包中的接口應(yīng)該被Mybatis識別為映射器(Mapper)。在多數(shù)據(jù)源配置中,可以使用不同的@MapperScan注解來指定不同數(shù)據(jù)源的映射器。
更進一步,SpringBoot集成Mybatis實現(xiàn)多數(shù)據(jù)源的基本流程如下:
- 為每個數(shù)據(jù)源定義獨立的配置,包括
DataSource、SqlSessionFactory。 - 使用
@MapperScan為每個數(shù)據(jù)源指定Mapper接口的位置。 - 將配置好的
SqlSessionFactory交由SpringBoot容器進行管理
這樣,當應(yīng)用程序運行時,只需要注入不同數(shù)據(jù)源對應(yīng)的Mapper即可訪問不同的數(shù)據(jù)庫,而無需擔(dān)心數(shù)據(jù)源之間的沖突和干擾。
最后,希望本文對你對有助于加深理解SpringBoot集成Mybatis的原理。
以上就是SpringBoot集成Mybatis實現(xiàn)對多數(shù)據(jù)源訪問原理的詳細內(nèi)容,更多關(guān)于SpringBoot Mybatis多數(shù)據(jù)源訪問的資料請關(guān)注腳本之家其它相關(guān)文章!
- MyBatisPuls多數(shù)據(jù)源操作數(shù)據(jù)源偶爾報錯問題
- Mybatis-plus配置多數(shù)據(jù)源,連接多數(shù)據(jù)庫方式
- MyBatis-Plus多數(shù)據(jù)源的示例代碼
- Seata集成Mybatis-Plus解決多數(shù)據(jù)源事務(wù)問題
- 詳解SpringBoot Mybatis如何對接多數(shù)據(jù)源
- Mybatis操作多數(shù)據(jù)源的實現(xiàn)
- 一文搞懂MyBatis多數(shù)據(jù)源Starter實現(xiàn)
- Mybatis-plus多數(shù)據(jù)源配置的兩種方式總結(jié)
- MyBatis-Plus 集成動態(tài)多數(shù)據(jù)源的實現(xiàn)示例
- Mybatis-Plus的多數(shù)據(jù)源你了解嗎
- mybatis-flex實現(xiàn)多數(shù)據(jù)源操作
相關(guān)文章
Maven中plugins和pluginManagement區(qū)別小結(jié)
pluginManagement是表示插件聲明,plugins就是直接引入一個plugin,本文主要介紹了Maven中plugins和pluginManagement區(qū)別小結(jié),具有一定的參考價值,感興趣的可以了解一下2024-06-06
SpringBoot之通過BeanPostProcessor動態(tài)注入ID生成器案例詳解
這篇文章主要介紹了SpringBoot之通過BeanPostProcessor動態(tài)注入ID生成器案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-09-09
java經(jīng)典問題:連個字符串互為回環(huán)變位
連個字符串互為回環(huán)變位經(jīng)常出現(xiàn)在java程序員面試中,這個是考驗程序員的解題思路和方法的最經(jīng)典的一題,小編為大家詳細分析一下,一起來學(xué)習(xí)吧。2017-11-11
springsecurity6配置自定義路徑身份認證的實現(xiàn)
本文主要介紹了springsecurity6配置自定義路徑身份認證的實現(xiàn),通過使用自定義的AuthorizationManager和MyService,可以實現(xiàn)更靈活的訪問控制,感興趣的可以了解一下2025-03-03

