mybatis 的动态数据源2

config包下

/**
 * 注入动态数据源
 */
public class DynamicDataSource  extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceContextHolder.getDataSource();
    }
}
/**
 * 配置数据源并注入到 DynamicDataSource
 */
@Configuration
public class DateSourceConfig {
    /**
     * yml 属性
     */
    @Autowired
    private Environment environment;
    @Autowired
    UserMapper userMapper;


    @Bean
    @Primary
    public DataSource dynamicDataSource() {
         DynamicDataSource dynamicDataSource = new DynamicDataSource();
         Map<Object, Object> dataSourceMap = new HashMap<>(); //全部数据源

        // 可以循环读库加配置
        // master
        DataSource master = buildDataSource(
                environment.getProperty("spring.datasource.dynamic.master.url"),
                environment.getProperty("spring.datasource.dynamic.master.username"),
                environment.getProperty("spring.datasource.dynamic.master.password"));
        // slave
        DataSource slave = buildDataSource(
                environment.getProperty("spring.datasource.dynamic.slave.url"),
                environment.getProperty("spring.datasource.dynamic.slave.username"),
                environment.getProperty("spring.datasource.dynamic.slave.password"));
        // 添加全部数据源
        dataSourceMap.put("master", master);
        dataSourceMap.put("slave", slave);
        dynamicDataSource.setTargetDataSources(dataSourceMap);
        // 默认数据源
        dynamicDataSource.setDefaultTargetDataSource(master);
        return dynamicDataSource;
    }

    public static DataSource buildDataSource(String url, String username, String password) {
        HikariDataSource dataSource = new HikariDataSource();
        dataSource.setJdbcUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return dataSource;
    }
}
/**
 * 当前线程对应的数据源
 */
public class DataSourceContextHolder {
    //此类提供线程局部变量。这些变量不同于它们的正常对应关系是每个线程访问一个线程(通过get、set方法),有自己的独立初始化变量的副本。
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    public static void setDataSource(String dataSource) {
        contextHolder.set(dataSource);
    }

    public static String getDataSource() {
        return contextHolder.get();
    }

    public static void clearDataSource() {
        contextHolder.remove();
    }
}

aop包下

/**
 * 动态数据源注解
 */
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DS {
    String value() default "master";
}
@Aspect
@Component
@Slf4j
public class DSAspect {

    @Pointcut("@annotation(com.my.config.aop.DS)")
    public void dataSourcePointcut(){}

    /**
     * 获取DS注解并设置 master 或 slave值 设置数据源
     * @param point
     * @return
     * @throws Throwable
     */
    @Around("dataSourcePointcut()")
    public Object datasourceAround(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature)point.getSignature();
        Method method = signature.getMethod();
        DS ds = method.getAnnotation(DS.class);
        if (Objects.nonNull(ds)){
            DataSourceContextHolder.setDataSource(ds.value());
        }
        try {
            return point.proceed();
        } finally {
            DataSourceContextHolder.clearDataSource();
        }
    }
}

启动类

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

yml

spring:
  datasource:
    dynamic:
      primary: master # 设置主数据源
      master:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url:  jdbc:mysql://localhost:3307/mybatis
        username: root
        password: phpts
      slave:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3307/mybatis_slave
        username: root
        password: phpts

pom

 		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        
		<!-- mybatis起步依赖 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

你可能感兴趣的:(mybatis)