SpringBoot多数据源动态切换+统一事务配置+动态分页方言

本文介绍了在SpringBoot项目中如何实现多数据源动态切换、统一事务管理和动态分页方言配置。通过创建AbstractRoutingDataSource子类DynamicDataSource,结合DbContextHolder利用ThreadLocal存储数据源,以及在MybatisPlusConfig中配置数据源、事务管理,最后使用AOP拦截器实现方法和类级别的数据源切换。启动类中排除默认数据源配置,提供完整代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot多数据源动态切换+统一事务配置+动态分页方言

需求驱动技术发展

最近有公司项目有一个动态切换数据源的需求,但是网上找到的多半不能用或者是功能不全,自己摸索出了最终配置,在此记录下,帮助下有同样需求的人。

不墨迹直接贴代码

我的项目是分层项目,我选择在Service层写动态切换,因为可以在业务层随意切换数据源,很方便

首先定义AbstractRoutingDataSource,这个类是Spring为我们提供的用来动态切换数据源的路由基类,我们只需要实现它并且重写determineCurrentLookupKey方法即可,目的是在Spring选择数据源的时候由我们来动态的指定数据源的Key。

DynamicDataSource :

import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * AbstractRoutingDataSource 类为Spring提供的多数据源路由的基类
 * 继承此类实现determineCurrentLookupKey方法返回一个数据源的Key即可动态的切换数据源
 *
 * @author wangjie-pc
 */
public class DynamicDataSource extends AbstractRoutingDataSource implements InitializingBean {
   
   

    /**
     * 取得当前使用哪个数据源
     *
     * @return
     */
    @Override
    protected Object determineCurrentLookupKey() {
   
   
        return DbContextHolder.getDbType();
    }

}

然后创建 DbContextHolder 数据源切换器,数据源切换器的目的是使用ThreadLocal来存储我们当前线程的数据源,实现不同线程不干扰,这点很重要,并且在切换数据源的时候动态的切换分页方言,因为项目使用的Mybatis-plus,可能切换方式有所不同,各位自行查询自己使用的持久层框架如何切换吧

DbContextHolder:


import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.tties.prepaid.enums.DBTypeEnum;
import com.tties.prepaid.service.SpringContextBeanService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import java.lang.reflect.Method;

/**
 * 切换数据源Holder
 *
 * @author wangjie-pc
 */
@Slf4j
public class DbContextHolder {
   
   

    private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();

    /**
     * 设置数据源
     *
     * @param dbTypeEnum
     */
    public static void setDbType(DBTypeEnum dbTypeEnum) {
   
   
        //切换数据源
        CONTEXT_HOLDER.set(dbTypeEnum.getValue());
        //切换分页插件方言
        try {
   
   
            DynamicDataSource dynamicDataSource = SpringContextBeanService.getBean(DynamicDataSource.class);
            Method determineTargetDataSourceMethod = BeanUtils.findDeclaredMethod(AbstractRoutingDataSource.class, "determineTargetDataSource");
            determineTargetDataSourceMethod.setAccessible(true);
            String type = ((DruidDataSource) determineTargetDataSourceMethod.invoke(dynamicDataSource)).getDbType();
            //切换分页方言
            SpringContextBeanService.getBean(PaginationInterceptor.class).setDialectType(type);
        } catch (Exception e) {
   
   
            log.error("Dialect Switching Failed!", e);
        }
    }

    /**
     * 取得当前数据源
     *
     * @return
     */
    public static String getDbType() {
   
   
        return CONTEXT_HOLDER.get();
    }

    /**
     * 清除上下文数据
     */
    public static void clearDbType() {
   
   
        CONTEXT_HOLDER.remove();
    }
}

接下来是重头戏MybatisPlusConfig,在这个类里面我们会配置数据源、多数据源管理器、事务

MybatisPlusConfig:


im
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值