詳解SpringBoot Mybatis如何對(duì)接多數(shù)據(jù)源
引言
在我們開發(fā)一些具有綜合功能的項(xiàng)目時(shí),往往會(huì)碰到一種情況,需要同時(shí)連接多個(gè)數(shù)據(jù)庫,這個(gè)時(shí)候就需要用到多數(shù)據(jù)源的設(shè)計(jì)。而Spring 與 Myabtis 其實(shí)做了多數(shù)據(jù)源的適配,只需少許改動(dòng)即可對(duì)接多數(shù)據(jù)源。本期我們就貼近實(shí)戰(zhàn),以一個(gè)單數(shù)據(jù)源的Demo為例,講述將其改為多數(shù)據(jù)源項(xiàng)目的過程,希望大家能有所體會(huì)
一、數(shù)據(jù)源的定義
數(shù)據(jù)源(Data Source)是指數(shù)據(jù)存儲(chǔ)的地方,大多數(shù)情況是指數(shù)據(jù)庫,不過文件服務(wù)器、傳感器、API等也能算數(shù)據(jù)源,主要是提供了對(duì)數(shù)據(jù)的訪問和操作。數(shù)據(jù)源中存儲(chǔ)了所有建立數(shù)據(jù)庫連接的信息。就像通過指定文件名稱可以在文件系統(tǒng)中找到文件一樣,通過提供正確的數(shù)據(jù)源名稱,你可以找到相應(yīng)的數(shù)據(jù)庫連接

二、單數(shù)據(jù)源配置
因?yàn)镾pringBoot對(duì)數(shù)據(jù)源有著高度的默認(rèn)配置,只配置一個(gè)數(shù)據(jù)源時(shí),該數(shù)據(jù)源會(huì)被作為默認(rèn),所以對(duì)接單數(shù)據(jù)源其實(shí)是非常簡(jiǎn)單的。如果你的工程采用的yaml格式配置文件,我們僅需做如下配置:
spring:
#數(shù)據(jù)庫連接配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/springtest
username: root
password: root如果是采用properties配置文件的也是一樣的:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springtest spring.datasource.username=root spring.datasource.password=root
三、如何配置多數(shù)據(jù)源
1. 工程層級(jí)調(diào)整
我們以曾經(jīng)搭建的工程為原始模板,進(jìn)行對(duì)接多數(shù)據(jù)源的操作。沒看過的可以點(diǎn)此查看: 從零開始,手把手教你搭建Spring Boot后臺(tái)工程并說明

因?yàn)閮H變動(dòng)數(shù)據(jù)源,所以我們不改動(dòng)其他層級(jí),僅僅將 mapper 拆為 mapper1 與 mapper2 兩部分

2. Spring項(xiàng)目配置
然后我們需要在 application.properties 或者 application.yml 中定義多個(gè)數(shù)據(jù)源:
spring:
#數(shù)據(jù)庫連接配置
datasource1:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/springtest2
username: root
password: root
datasource2:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/springtest
username: root
password: root這里有兩個(gè)細(xì)節(jié)需要注意:
- 因?yàn)槲覀儧Q定使用雙數(shù)據(jù)源,所以把數(shù)據(jù)源的連接配置改成了
datasource1和datasource2。而不再保留datasource,這樣SpringBoot就不再會(huì)為我們?cè)O(shè)定默認(rèn)數(shù)據(jù)庫 - 因?yàn)槲覀兡壳安捎玫?nbsp;springBoot2.5.2,默認(rèn)的連接池為
Hikari,該連接池?cái)?shù)據(jù)源的地址字段為jdbc-url而非url。在只有單個(gè)數(shù)據(jù)源時(shí),SpringBoot走默認(rèn)數(shù)據(jù)源邏輯為我們把url與jdbc-url進(jìn)行映射,保證我們獲得數(shù)據(jù)源。此時(shí)我們自己設(shè)置的數(shù)據(jù)源沒有進(jìn)行映射處理,就需要保證字段符合Hikari的要求。否則會(huì)出現(xiàn)java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName異常
3. 會(huì)話配置
僅有配置文件可不行,接下來,我們需要在代碼中讀取到配置,并建立兩個(gè)數(shù)據(jù)源。如下,每個(gè)數(shù)據(jù)源都有隔離的mapper接口、xml文件、會(huì)話工廠及會(huì)話模板
第一個(gè)數(shù)據(jù)源 如下(示例):
@Configuration
@MapperScan(basePackages = "com.zhanfu.springboot.demo.mapper1", sqlSessionFactoryRef = "sqlSessionFactory1")
public class DataSource1Config {
@Bean
@ConfigurationProperties(prefix = "spring.datasource1")
public DataSource dataSource1() {
return DataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory sqlSessionFactory1() throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource1());
String locationPattern = "classpath*:/mapper1/*.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);
}
}配置第二個(gè)數(shù)據(jù)源 DataSource2Config
@Configuration
@MapperScan(basePackages = "com.zhanfu.springboot.demo.mapper2", sqlSessionFactoryRef = "sqlSessionFactory2")
public class DataSource2Config {
@Bean
@ConfigurationProperties(prefix = "spring.datasource2")
public DataSource dataSource2() {
return DataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory sqlSessionFactory2() throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource2());
String locationPattern = "classpath*:/mapper2/*.xml";
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
return sessionFactoryBean.getObject();
}
@Bean(name = "sqlSessionTemplate2")
public SqlSessionTemplate sqlSessionTemplate2(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "productMapper")
public ProductMapper mapper2(@Qualifier("sqlSessionTemplate2") SqlSessionTemplate sqlSessionTemplate) throws Exception {
return sqlSessionTemplate.getMapper(ProductMapper.class);
}
}4. 事務(wù)管理器
為兩個(gè)數(shù)據(jù)源分別配置自己的事務(wù)管理器,如果你的項(xiàng)目里通篇沒有方法級(jí)別的事務(wù)(一個(gè)SQL就是一個(gè)事務(wù)),那不設(shè)置這個(gè)也不影響,否則還是建議加上。
@Configuration
public class TransactionManagerConfig {
@Autowired
private DataSource dataSource1;
@Autowired
private DataSource dataSource2;
@Bean
public PlatformTransactionManager txManager1() {
return new DataSourceTransactionManager(dataSource1);
}
@Bean
public PlatformTransactionManager txManager2() {
return new DataSourceTransactionManager(dataSource2);
}
}四、驗(yàn)證
我們把兩張表拆進(jìn)兩個(gè)庫中,以兩個(gè)庫模擬兩個(gè)數(shù)據(jù)源,使得程序可以同時(shí)連接兩個(gè)庫

瀏覽器輸入 http://127.0.0.1:8080/user/findall 查詢接口成功

再在瀏覽器輸入 http://127.0.0.1:8080/product/findall 查詢第二個(gè)庫的數(shù)據(jù)亦成功返回

這樣我們就完成了一個(gè)工程同時(shí)連接兩個(gè)數(shù)據(jù)源。
總結(jié)
經(jīng)過上述的操作,我們已經(jīng)成功把項(xiàng)目對(duì)接了多數(shù)據(jù)源。當(dāng)然,方案肯定不止這一種,后續(xù)圍繞該問題,我們還會(huì)講解其他方式。但不論是什么方式,主旨都是加深大家對(duì)SpringBoot 和 Mybatis的理解,我們?cè)?jīng)梳理過全流程,但只是蜻蜓點(diǎn)水帶大家看一遍大體輪廓,并不足以讓你精通,后面本專欄將繼續(xù)深入講解,更多關(guān)于SpringBoot Mybatis對(duì)接多數(shù)據(jù)源的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- MyBatisPuls多數(shù)據(jù)源操作數(shù)據(jù)源偶爾報(bào)錯(cuò)問題
- Mybatis-plus配置多數(shù)據(jù)源,連接多數(shù)據(jù)庫方式
- MyBatis-Plus多數(shù)據(jù)源的示例代碼
- SpringBoot集成Mybatis實(shí)現(xiàn)對(duì)多數(shù)據(jù)源訪問原理
- Seata集成Mybatis-Plus解決多數(shù)據(jù)源事務(wù)問題
- Mybatis操作多數(shù)據(jù)源的實(shí)現(xiàn)
- 一文搞懂MyBatis多數(shù)據(jù)源Starter實(shí)現(xiàn)
- Mybatis-plus多數(shù)據(jù)源配置的兩種方式總結(jié)
- MyBatis-Plus 集成動(dòng)態(tài)多數(shù)據(jù)源的實(shí)現(xiàn)示例
- Mybatis-Plus的多數(shù)據(jù)源你了解嗎
- mybatis-flex實(shí)現(xiàn)多數(shù)據(jù)源操作
相關(guān)文章
springboot整合xxl-job的實(shí)現(xiàn)示例
本文主要介紹了springboot整合xxl-job的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
SpringLDAP連接LDAPS證書報(bào)錯(cuò)問題及解決
這篇文章主要介紹了SpringLDAP連接LDAPS證書報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
IDEA2020如何打開Run Dashboard的方法步驟
這篇文章主要介紹了IDEA2020如何打開Run Dashboard的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
Spring?MVC基于注解的使用之JSON數(shù)據(jù)處理的方法
這篇文章主要介紹了Spring?MVC基于注解的使用JSON數(shù)據(jù)處理,json是一種輕量級(jí)的數(shù)據(jù)交換格式,是一種理想的數(shù)據(jù)交互語言,它易于閱讀和編寫,同時(shí)也易于機(jī)器解析和生成,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Java Synchronized鎖升級(jí)原理及過程剖析
這篇文章主要為大家詳細(xì)介紹一下Java中Synchronized鎖升級(jí)原理及過程,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)學(xué)習(xí)2022-08-08
SparkStreaming-Kafka通過指定偏移量獲取數(shù)據(jù)實(shí)現(xiàn)
這篇文章主要為大家介紹了SparkStreaming-Kafka通過指定偏移量獲取數(shù)據(jù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
Java8中對(duì)于LocalDateTime的序列化和反序列化問題
這篇文章主要介紹了Java8中對(duì)于LocalDateTime的序列化和反序列化問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06
SpringBoot中動(dòng)態(tài)數(shù)據(jù)源是實(shí)現(xiàn)與用途
這篇文章主要是來和大家討論一下SpringBoot中動(dòng)態(tài)數(shù)據(jù)源是實(shí)現(xiàn)與用途,文中的示例代碼簡(jiǎn)潔易懂,具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下2023-08-08

