Mybatis-plus配置多數(shù)據(jù)源,連接多數(shù)據(jù)庫(kù)方式
前言
工作的時(shí)候,遇到了需要將一個(gè)數(shù)據(jù)庫(kù)的一些數(shù)據(jù)插入或更新到另一個(gè)數(shù)據(jù)庫(kù)。
一開(kāi)始使用
insert into TABLE (col1,col2) VALUES (val1,val2) ON DUPLICATE KEY update col1 = "val1";
(這句sql語(yǔ)句的意思是:將val1,val2值插入到TABLE表的col1和col2字段中,如果出現(xiàn)主鍵或唯一沖突,就進(jìn)行更新,只將col1值更新為val1)進(jìn)行數(shù)據(jù)的插入和更新。
但是每次都要對(duì)著這一條sql語(yǔ)句進(jìn)行修改,十分麻煩,就想著能否同時(shí)連接兩個(gè)數(shù)據(jù)庫(kù)進(jìn)行業(yè)務(wù)處理。
業(yè)務(wù)邏輯

使用Mybatis實(shí)現(xiàn)
首先,如果你的項(xiàng)目用的是Mybatis,那么以下配置可以實(shí)現(xiàn)配置多數(shù)據(jù)源,連接多數(shù)據(jù)庫(kù)的作用。但是,如果你使用的是Mybatis-plus,本人建議使用Mybatis-plus實(shí)現(xiàn)更加簡(jiǎn)單易操作。
1、在yml配置文件中配置多數(shù)據(jù)庫(kù)
例如:
spring:
application:
name: CONNECTION
datasource:
db1:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
username: root
password: 123456
type: com.alibaba.druid.pool.DruidDataSource
db2:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://11.11.11.11:3306/test?serverTimezone=UTC
username: root
password: 654321
type: com.alibaba.druid.pool.DruidDataSource
注意,將數(shù)據(jù)庫(kù)配置中的url改為jdbc-url,否則無(wú)法配置多數(shù)據(jù)源。
2、創(chuàng)建不同的mapper,用于不同的數(shù)據(jù)庫(kù)

3、編寫(xiě)數(shù)據(jù)源的配置類(lèi)
例如:
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.czf.connect.mapper.db1", sqlSessionTemplateRef = "db1SqlSessionTemplate")
//此處的basePackages指向的是你存放數(shù)據(jù)庫(kù)db1的mapper的包
public class DataSource1Config {
@Bean(name = "db1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.db1")//指向yml配置文件中的數(shù)據(jù)庫(kù)配置
@Primary //主庫(kù)加這個(gè)注解,修改優(yōu)先權(quán),表示發(fā)現(xiàn)相同類(lèi)型bean,優(yōu)先使用該方法。
public DataSource dbDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db1SqlSessionFactory")
@Primary
public SqlSessionFactory dbSqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*xml"));
//這個(gè)的getResources指向的是你的mapper.xml文件,相當(dāng)于在yml中配置的mapper-locations,此處配置了yml中就不用配置,或者說(shuō)不會(huì)讀取yml中的該配置。
return bean.getObject();
}
@Bean(name = "db1TransactionManager")
@Primary
public DataSourceTransactionManager dbTransactionManager(@Qualifier("db1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "db1SqlSessionTemplate")
@Primary
public SqlSessionTemplate dbSqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
數(shù)據(jù)庫(kù)db2的配置類(lèi):
@Configuration
@MapperScan(basePackages = "com.czf.connect.mapper.db2", sqlSessionTemplateRef = "db2SqlSessionTemplate")
public class DataSource2Config {
@Bean(name = "db2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.db2")
public DataSource dbDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "db2SqlSessionFactory")
public SqlSessionFactory dbSqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*xml"));
return bean.getObject();
}
@Bean(name = "db2TransactionManager")
public DataSourceTransactionManager dbTransactionManager(@Qualifier("db2DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "db2SqlSessionTemplate")
public SqlSessionTemplate dbSqlSessionTemplate(@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
整體結(jié)構(gòu):

至此,需要修改或查詢(xún)哪個(gè)數(shù)據(jù)庫(kù),只需要在對(duì)應(yīng)的com///mapper/db包中創(chuàng)建對(duì)應(yīng)的mapper類(lèi)或者編寫(xiě)特定的sql語(yǔ)句即可。
使用Mybatis-plus實(shí)現(xiàn)
Mybatis-plus官網(wǎng)很清楚的告訴了我們?nèi)绾闻渲枚鄶?shù)據(jù)源。
1、引入dynamic-datasource-spring-boot-starter
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${version}</version>
</dependency>2、配置數(shù)據(jù)源
spring:
datasource:
dynamic:
primary: mysql1 #設(shè)置默認(rèn)的數(shù)據(jù)源或者數(shù)據(jù)源組,默認(rèn)值即為mysql1
strict: false #嚴(yán)格匹配數(shù)據(jù)源,默認(rèn)false. true未匹配到指定數(shù)據(jù)源時(shí)拋異常,false使用默認(rèn)數(shù)據(jù)源
datasource:
mysql1:
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver # 3.2.0開(kāi)始支持SPI可省略此配置
mysql2:
url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
mysql2:
url: ENC(xxxxx) # 內(nèi)置加密,使用請(qǐng)查看詳細(xì)文檔
username: ENC(xxxxx)
password: ENC(xxxxx)
driver-class-name: com.mysql.jdbc.Driver
#......省略
3、使用 @DS 切換數(shù)據(jù)源
@DS 可以注解在方法上或類(lèi)上,同時(shí)存在就近原則 方法上注解 優(yōu)先于 類(lèi)上注解。
| 注解 | 結(jié)果 |
|---|---|
| 沒(méi)有@DS | 默認(rèn)數(shù)據(jù)源 |
| @DS(“dsName”) | dsName可以為組名也可以為具體某個(gè)庫(kù)的名稱(chēng) |
@Service
@DS("mysql1")
public class UserServiceImpl implements UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
public List selectAll() {
return jdbcTemplate.queryForList("select * from user");
}
@Override
@DS("mysql2")
public List selectByCondition() {
return jdbcTemplate.queryForList("select * from user where age >10");
}
}
在這里會(huì)有個(gè)小問(wèn)題,假如我編寫(xiě)了兩個(gè)方法,方法A使用的是 @DS(“mysql1”) ,功能是查詢(xún)mysql1中的數(shù)據(jù);方法B調(diào)用的是@DS(“mysql2”),是將數(shù)據(jù)插入到mysql2數(shù)據(jù)庫(kù)中,那么我想在方法B中調(diào)用方法A,實(shí)現(xiàn)mysql1中查詢(xún)的數(shù)據(jù)插入到mysql2中,能夠成功嗎?
答案是:不可以。
要想實(shí)現(xiàn)這個(gè)功能,我們可以使用多數(shù)據(jù)源的一個(gè)類(lèi),簡(jiǎn)單來(lái)說(shuō)是一個(gè)隊(duì)列,將需要使用到的數(shù)據(jù)源push進(jìn)行,不用時(shí)再poll掉。就不用使用@DS注解了。
比如:
@RequestMapping("/Bmetohd")
public int Bmethod(){
DynamicDataSourceContextHolder.push("mysql1");
List<User> users = Amethod();
DynamicDataSourceContextHolder.poll();
DynamicDataSourceContextHolder.push("mysql2");
int num = 0;
for(User user: users){
int i = User2Mapper.insert(user);
num += i;
}
DynamicDataSourceContextHolder.poll();
return num;
}
重點(diǎn):
DynamicDataSourceContextHolder.push("mysql1");
//業(yè)務(wù)代碼
DynamicDataSourceContextHolder.poll();
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot項(xiàng)目中多數(shù)據(jù)源配置方法與使用場(chǎng)景
- SpringBoot進(jìn)行多數(shù)據(jù)源配置的詳細(xì)步驟
- SpringBoot多數(shù)據(jù)源配置完整指南
- Mybatis+Druid+MybatisPlus多數(shù)據(jù)源配置方法
- SpringBoot中配置多數(shù)據(jù)源的方法詳解
- springboot配置多數(shù)據(jù)源(靜態(tài)和動(dòng)態(tài)數(shù)據(jù)源)
- SpringBoot+mybatis-plus實(shí)現(xiàn)多數(shù)據(jù)源配置的詳細(xì)步驟
相關(guān)文章
MyBatis Generator配置生成接口和XML映射文件的實(shí)現(xiàn)
本文介紹了配置MBG以生成Mapper接口和XML映射文件,過(guò)合理使用MBG和自定義生成策略,可以有效解決生成的Example類(lèi)可能帶來(lái)的問(wèn)題,使代碼更加簡(jiǎn)潔和易于維護(hù)2025-02-02
SpringBoot無(wú)法使用jkd8問(wèn)題的解決方法
這篇文章主要介紹了SpringBoot無(wú)法使用jkd8問(wèn)題的解決方法,文中通過(guò)圖文結(jié)合的形式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-12-12
spring boot整合log4j2及MQ消費(fèi)處理系統(tǒng)日志示例
這篇文章主要為大家介紹了spring boot整合log4j2及MQ消費(fèi)處理系統(tǒng)日志的示例過(guò)程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-03-03
IDEA2021沒(méi)有Web?Application的解決過(guò)程及分析
在IDEA中創(chuàng)建WebApplication項(xiàng)目時(shí),若AddFrameworksSupport無(wú)該選項(xiàng),可先創(chuàng)建普通Java項(xiàng)目后添加框架支持,或通過(guò)快捷鍵打開(kāi)registry,勾選javaee.legacy.project.wizard以啟用,如解決您的問(wèn)題,歡迎點(diǎn)贊支持2025-09-09
SpringBoot熱部署和整合Mybatis的過(guò)程
熱部署,就是在應(yīng)用正在運(yùn)行的時(shí)候升級(jí)軟件,卻不需要重新啟動(dòng)應(yīng)用,本文給大家詳細(xì)介紹SpringBoot熱部署和整合Mybatis的過(guò)程,感興趣的朋友跟隨小編一起看看吧2023-10-10
細(xì)談java同步之JMM(Java Memory Model)
Java內(nèi)存模型是在硬件內(nèi)存模型上的更高層的抽象,它屏蔽了各種硬件和操作系統(tǒng)訪問(wèn)的差異性,保證了Java程序在各種平臺(tái)下對(duì)內(nèi)存的訪問(wèn)都能達(dá)到一致的效果。下面我們來(lái)一起學(xué)習(xí)下JMM2019-05-05
SpringBoot+Vue項(xiàng)目新手快速入門(mén)指南
最近剛剛做了一個(gè)基于vue+springboot的系統(tǒng),于是基于這點(diǎn),對(duì)遇到的一些問(wèn)題進(jìn)行一些配置的匯總,下面這篇文章主要給大家介紹了關(guān)于SpringBoot+Vue項(xiàng)目新手快速入門(mén)的相關(guān)資料,需要的朋友可以參考下2022-06-06

