整合动态数据源

7/6/2023

# 导入依赖


<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.30</version>
    </dependency>

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.2</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.15</version>
    </dependency>

</dependencies>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 编写配置文件

spring:
  datasource:
    master:
      driver-class-name: com.mysql.cj.jdbc.Driver
#      type: com.alibaba.druid.pool.DruidDataSource
      url: jdbc:mysql://127.0.0.1:3306/transaction_test?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false
      username: root
      password: root
    slaver:
      driver-class-name: com.mysql.cj.jdbc.Driver
#      type: com.alibaba.druid.pool.DruidDataSource
      url: jdbc:mysql://127.0.0.1:3306/transaction_test?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false
      username: root
      password: root

mybatis-plus:
  mapper-locations:
    - classpath*:mapper/*.xml              # 定义 xml 存放位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 服务编写

# 继承动态数据源

public class DynamicDataSource extends AbstractRoutingDataSource {

    public static final ThreadLocal<String> dataSourceKey = new ThreadLocal<>();

    @Override
    protected Object determineCurrentLookupKey() {
        return dataSourceKey.get();
    }


}
1
2
3
4
5
6
7
8
9
10
11

# 数据源配置

@Configuration
public class DataSourceConfig {

    // 动态数据源配置
    @Bean
    @Primary
    public DynamicDataSource dynamicDataSource(DruidDataSource masterDataSource, DruidDataSource slaverDataSource) {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 设置默认数据源
        dynamicDataSource.setDefaultTargetDataSource(masterDataSource);

        // 注入所有数据源
        Map<Object, Object> map = new HashMap<>();
        map.put("master", masterDataSource);
        map.put("slaver", slaverDataSource);
        dynamicDataSource.setTargetDataSources(map);

        return dynamicDataSource;
    }
    
    @Bean
    @ConfigurationProperties("spring.datasource.master")
    public DataSourceProperties masterDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.slaver")
    public DataSourceProperties slaverDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    public DruidDataSource masterDataSource(DataSourceProperties masterDataSourceProperties) {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUsername(masterDataSourceProperties.getUsername());
        druidDataSource.setPassword(masterDataSourceProperties.getPassword());
        druidDataSource.setUrl(masterDataSourceProperties.getUrl());
        return druidDataSource;
    }

    @Bean
    public DruidDataSource slaverDataSource(DataSourceProperties slaverDataSourceProperties) {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUsername(slaverDataSourceProperties.getUsername());
        druidDataSource.setPassword(slaverDataSourceProperties.getPassword());
        druidDataSource.setUrl(slaverDataSourceProperties.getUrl());
        return druidDataSource;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# 2.编写数据源注解

@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface KingDataSource {

    String value() default "master";

}
1
2
3
4
5
6
7
8

# 数据源切面

@Aspect
@Component
public class DynamicDataSourceAspect {

    @Pointcut("execution(* com.wenking.daynamicdatasource..*(..))")
    public void pointCut() {
    }


    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        MethodSignature signature =(MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        
        KingDataSource annotation = AnnotationUtils.findAnnotation(method.getDeclaringClass(), KingDataSource.class);

        if (annotation != null) {
            String dataSourceKey = annotation.value();
            DynamicDataSource.dataSourceKey.set(dataSourceKey);
        }
    }


    @After("pointCut()")
    public void after() {
        DynamicDataSource.dataSourceKey.set(null);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28