Spring MVC+Mybatis 多数据源配置

本文详细介绍了在Spring MVC+Mybatis环境下如何配置多数据源,包括继承AbstractRoutingDataSource、使用线程内部数据源处理类、自定义数据源注解、AOP拦截切换数据源、配置数据源以及解决AOP顺序问题。通过这些步骤,实现了根据业务需求灵活切换数据库的能力。
摘要由CSDN通过智能技术生成

随着业务的不断扩张,应用压力逐渐增大,特别是数据库。不论从读写分离还是分库的方法来提高应用的性能,都需要涉及到多数据源问题。本文主要介绍在Spring MVC+Mybatis下的多数据源配置。主要通过Spring提供的AbstractRoutingDataSource来实现多数据源。

1. 继承AbstractRoutingDataSource

AbstractRoutingDataSource 是spring提供的一个多数据源抽象类。spring会在使用事务的地方来调用此类的determineCurrentLookupKey()方法来获取数据源的key值。我们继承此抽象类并实现此方法:

@Order(2)
public class DynamicDataSource extends AbstractRoutingDataSource {

    private static final Logger logger = LogManager.getLogger(DynamicDataSource.class);

    @Override
    protected Object determineCurrentLookupKey() {
        logger.info("当前数据源为:"+DataSourceContextHolder.getDB());
        return DataSourceContextHolder.getDB();
    }
}

2. 线程内部数据源处理类

public class DataSourceContextHolder {

    private static final Logger logger = LogManager.getLogger(DataSourceContextHolder.class);

    /**
     * 默认数据源
     */
    public static final String DEFAULT_DS = "dataSource";

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

    /**
     * 设置数据源名
     * @param dbType
     */
    public static void setDB(String dbType) {
        contextHolder.set(dbType);
        logger.info("切换到{"+dbType+"}数据源");
    }

    /**
     * 获取数据源名
     * @return
     */
    public static String getDB() {
        if(contextHolder.get()==null){
            return DEFAULT_DS;
        }else{
            return (contextHolder.get());
        }
    }

    /**
     * 清除数据源名
     */
    public static void clearDB() {
        contextHolder.remove();
    }

3. 自定义数据源注解类

对于spring来说,注解即简单方便且可读性也高。所以,我们也通过注解在Mapper或service的方法前指定所用的数据源。我们先定义自己的注解类,其中value为数据源的key值,并初始化dataSource为默认数据源。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
public @interface DS {
    String value() default "dataSource";
}

4. AOP 拦截mapper并切换数据源

指定注解以后,我们可以通过AOP拦截所有mapper方法,在方法执行之前获取方法上的注解:即数据源的key值。

@Order(1)
@Aspect
public class DynamicDataSourceAspect {

    @After("@annotation(DS)")
    public void afterSwitchDS(JoinPoint point){
        DataSourceContextHolder.clearDB();
    }
    /**
       * 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
       *
       * @param point
       * @throws Exception
       */
    @Before("@annotation(DS)&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值