SpringMvc+mysql+mybatis多数据源实现

项目主要结构如下:


image.png
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface DataSourceSwitch {
    DBTypeEnum value() default DBTypeEnum.db1;
}


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
@Aspect
@Order(-100)
@Slf4j
public class DataSourceSwitchAspect {

    @Pointcut("execution(* com.*.*.*.sp.*.*.service..*.*(..))")
    private void db1Aspect() {

    }


    @Pointcut("execution(* com.*.*.*.sp.*.*.service..*.*(..))")
    private void db2Aspect() {

    }

    @Before("db1Aspect()")
    public void db1(JoinPoint joinPoint) {
        log.info("切换到db1Source 数据源...");
        setDataSource(joinPoint, DBTypeEnum.db1);
    }

    @Before("db2Aspect()" )
    public void db2 (JoinPoint joinPoint) {
        log.info("切换到db2Source 数据源...");
        setDataSource(joinPoint, DBTypeEnum.db2);
    }

    /**
     * 添加注解方式,如果有注解优先注解,没有则按传过来的数据源配置
     * @param joinPoint
     * @param dbTypeEnum
     */
    private void setDataSource(JoinPoint joinPoint, DBTypeEnum dbTypeEnum) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        DataSourceSwitch dataSourceSwitch = methodSignature.getMethod().getAnnotation(DataSourceSwitch.class);
        if (Objects.isNull(dataSourceSwitch) || Objects.isNull(dataSourceSwitch.value())) {
            DBContextHolder.setDBType(dbTypeEnum);
        }else{
            log.info("根据注解来切换数据源,注解值为:"+dataSourceSwitch.value());
            switch (dataSourceSwitch.value().getValue()) {
                case "db1":
                    DBContextHolder.setDBType(DBTypeEnum.db1);
                    break;
                case "db2":
                    DBContextHolder.setDBType(DBTypeEnum.db2);
                    break;
                default:
                    DBContextHolder.setDBType(dbTypeEnum);
            }
        }
    }
}



public class DBContextHolder {

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

    /**
     * 设置数据源
     * @param dbTypeEnum
     */
    public static void setDBType(DBTypeEnum dbTypeEnum) {
        contextHolder.set(dbTypeEnum.getValue());
    }

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

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


public enum DBTypeEnum {
    db1("db1"),
    db2("db1");

    private String value;

    DBTypeEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}


import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DBContextHolder.getDBType();
    }
}

serviceimpl层

  @DataSourceSwitch(DBTypeEnum.db1)
    @Override
    public dto find (String userid) {
        return testDao. find ( userid) ;
    }
 
    
        
            
                
                
            
        
        
        
    

你可能感兴趣的:(SpringMvc+mysql+mybatis多数据源实现)