整合动态数据源
wenking 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
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
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
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
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
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
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