springboot中mybatis多數(shù)據(jù)源動(dòng)態(tài)切換實(shí)現(xiàn)
在開發(fā)中,動(dòng)態(tài)數(shù)據(jù)源配置還是用的比較多的,比如在多數(shù)據(jù)源使用方面,又或者是在多個(gè)DB之間切換方面。這里給出一個(gè)動(dòng)態(tài)數(shù)據(jù)源的配置方案,兩個(gè)DB均以mysql為例。
多數(shù)據(jù)源配置引入
mybatis和mysql在springboot中的引入這里就不在說了,不了解的可以參見springboot中mysql與mybatis的引入。
數(shù)據(jù)源配置如下:
datasource:
master:
type: com.alibaba.druid.pool.DruidDataSource
jdbc-url: jdbc:mysql://127.0.0.1:3306/sbac_master?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver
log:
type: com.alibaba.druid.pool.DruidDataSource
jdbc-url: jdbc:mysql://127.0.0.1:3306/sbac_log?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis的配置引入如下:
mybatis: config-location: classpath:mybatis-config.xml mapper-locations: classpath:com/lazycece/sbac/mysql/data/dao/*/mapper/*.xml
這里已然使用的是springboot的自動(dòng)配置功能配置mybatis信息,只是手動(dòng)指定了數(shù)據(jù)源的。如下所示,指定了master和log兩個(gè)數(shù)據(jù)源,設(shè)置master為默認(rèn)數(shù)據(jù)源:
@Configuration
public class MultiDataSource {
public static final String MASTER_DATA_SOURCE = "masterDataSource";
public static final String LOG_DATA_SOURCE = "logDataSource";
@Bean(name = MultiDataSource.MASTER_DATA_SOURCE)
@ConfigurationProperties(prefix = "datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = MultiDataSource.LOG_DATA_SOURCE)
@ConfigurationProperties(prefix = "datasource.log")
public DataSource logDataSource() {
return DataSourceBuilder.create().build();
}
@Primary
@Bean(name = "dynamicDataSource")
public DynamicDataSource dataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setDefaultTargetDataSource(masterDataSource());
Map<Object, Object> dataSourceMap = new HashMap<>(4);
dataSourceMap.put(MASTER_DATA_SOURCE, masterDataSource());
dataSourceMap.put(LOG_DATA_SOURCE, logDataSource());
dynamicDataSource.setTargetDataSources(dataSourceMap);
return dynamicDataSource;
}
}
動(dòng)態(tài)數(shù)據(jù)源路由實(shí)現(xiàn)
引入了配置信息之后,便是該說如何實(shí)現(xiàn)多數(shù)據(jù)源切換了。我們是通過實(shí)現(xiàn)AbstractRoutingDataSource類的determineCurrentLookupKey方法來實(shí)現(xiàn)數(shù)據(jù)源的動(dòng)態(tài)路由,設(shè)置ThreadLocal線程保護(hù)變量存儲(chǔ)數(shù)據(jù)源key,確保線程間不受影響。
package com.lazycece.sbac.mysql.multi.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* @author lazycece
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSource.class);
private static final ThreadLocal<String> DATA_SOURCE_KEY = new ThreadLocal<>();
static void changeDataSource(String dataSourceKey) {
DATA_SOURCE_KEY.set(dataSourceKey);
}
static void clearDataSource() {
DATA_SOURCE_KEY.remove();
}
@Override
protected Object determineCurrentLookupKey() {
String key = DATA_SOURCE_KEY.get();
LOGGER.info("current data-source is {}", key);
return key;
}
}
隨后,便是用AOP的方式來實(shí)現(xiàn)數(shù)據(jù)源的動(dòng)態(tài)切換,注解和切面定義如下:
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface DataSource {
String value();
}
@Component
@Aspect
public class DataSourceConfig {
@Before("@annotation(dataSource)")
public void beforeSwitchDataSource(DataSource dataSource) {
DynamicDataSource.changeDataSource(dataSource.value());
}
@After("@annotation(DataSource)")
public void afterSwitchDataSource() {
DynamicDataSource.clearDataSource();
}
}
動(dòng)態(tài)數(shù)據(jù)源切換使用
動(dòng)態(tài)數(shù)據(jù)源切換只需要在業(yè)務(wù)中使用@DataSource注解來標(biāo)明需要使用的數(shù)據(jù)源即可,如下所示(這里只貼出關(guān)鍵代碼):
@Service
public class DynamicDataSourceServiceImpl implements DynamicDataSourceService {
@Resource
private UserDao userDao;
@Resource
private SystemLogDao systemLogDao;
@Override
@DataSource(value = MultiDataSource.MASTER_DATA_SOURCE)
public void addUserInfo(User user) {
userDao.insert(user);
}
@Override
@DataSource(value = MultiDataSource.MASTER_DATA_SOURCE)
public User getUserInfo(String username) {
return userDao.findByUsername(username);
}
@Override
@DataSource(value = MultiDataSource.LOG_DATA_SOURCE)
public void addSystemLog(SystemLog systemLog) {
systemLogDao.insert(systemLog);
}
@Override
@DataSource(value = MultiDataSource.LOG_DATA_SOURCE)
public List<SystemLog> getSystemLogInfo(Date beginTime, Date endTime) {
return systemLogDao.findByCreateTime(beginTime, endTime);
}
}
案例源碼
到此這篇關(guān)于springboot中mybatis多數(shù)據(jù)源動(dòng)態(tài)切換實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot mybatis多數(shù)據(jù)源動(dòng)態(tài)切換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot dynamic多數(shù)據(jù)源demo以及常見切換、事務(wù)的問題
- Springboot實(shí)現(xiàn)多數(shù)據(jù)源切換詳情
- SpringBoot多數(shù)據(jù)源配置并通過注解實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源
- SpringBoot基于AbstractRoutingDataSource實(shí)現(xiàn)多數(shù)據(jù)源動(dòng)態(tài)切換
- SpringBoot多數(shù)據(jù)源切換實(shí)現(xiàn)代碼(Mybaitis)
- SpringBoot實(shí)現(xiàn)多數(shù)據(jù)源的切換實(shí)踐
- SpringBoot?+DynamicDataSource切換多數(shù)據(jù)源的全過程
- Springboot如何設(shè)置多數(shù)據(jù)源,隨時(shí)切換
相關(guān)文章
java內(nèi)部類之成員內(nèi)部類、局部?jī)?nèi)部類和匿名內(nèi)部類用法及說明
這篇文章主要介紹了java內(nèi)部類之成員內(nèi)部類、局部?jī)?nèi)部類和匿名內(nèi)部類的用法及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
Spark Streaming編程初級(jí)實(shí)踐詳解
這篇文章主要為大家介紹了Spark Streaming編程初級(jí)實(shí)踐詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
java基于servlet使用組件smartUpload實(shí)現(xiàn)文件上傳
這篇文章主要介紹了java基于servlet使用組件smartUpload實(shí)現(xiàn)文件上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
基于jmeter實(shí)現(xiàn)跨線程組傳遞token過程圖解
這篇文章主要介紹了基于jmeter實(shí)現(xiàn)跨線程組傳遞token,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04

