千家信息网

springboot中怎么实现mybatis多数据源动态切换

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,这篇"springboot中怎么实现mybatis多数据源动态切换"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收
千家信息网最后更新 2025年02月02日springboot中怎么实现mybatis多数据源动态切换

这篇"springboot中怎么实现mybatis多数据源动态切换"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"springboot中怎么实现mybatis多数据源动态切换"文章吧。

多数据源配置引入

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为默认数据源:

@Configurationpublic 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 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 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@Aspectpublic class DataSourceConfig {    @Before("@annotation(dataSource)")    public void beforeSwitchDataSource(DataSource dataSource) {        DynamicDataSource.changeDataSource(dataSource.value());    }    @After("@annotation(DataSource)")    public void afterSwitchDataSource() {        DynamicDataSource.clearDataSource();    }}

动态数据源切换使用

动态数据源切换只需要在业务中使用@DataSource注解来标明需要使用的数据源即可,如下所示(这里只贴出关键代码):

@Servicepublic 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 getSystemLogInfo(Date beginTime, Date endTime) {        return systemLogDao.findByCreateTime(beginTime, endTime);    }}

以上就是关于"springboot中怎么实现mybatis多数据源动态切换"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

0