首頁 >Java >java教程 >springboot中怎麼實作mybatis多資料來源動態切換

springboot中怎麼實作mybatis多資料來源動態切換

WBOY
WBOY轉載
2023-05-12 19:43:041206瀏覽

多資料來源配置引入

mybatis和mysql在springboot中的引入這裡就不在說了,不了解的可以參考springboot中mysql與mybatis的引進。

資料來源配置如下:

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的自動設定功能配置mybatis訊息,只是手動指定了資料來源的。如下所示,指定了master和log兩個資料來源,設定master為預設資料來源:

@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;
    }
}

#動態資料來源路由實作

##引入了設定資訊之後,便是該說如何實現多重資料來源切換了。我們是透過實作AbstractRoutingDataSource類別的determineCurrentLookupKey方法來實現資料來源的動態路由,設定ThreadLocal執行緒保護變數儲存資料來源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的方式來實現資料來源的動態切換,註解和切面定義如下:


@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();
    }
}

動態資料來源切換使用


動態資料來源切換只需要在業務中使用@DataSource註解來標示需要使用的資料來源即可,如下所示(這裡只貼出關鍵程式碼):


@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);
    }
}

以上是springboot中怎麼實作mybatis多資料來源動態切換的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除