springboot mybatis 多数据源
2022-02-09 本文已影响0人
剑子仙迹
依赖
Pom 中导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<!-- 连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
<!-- aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
习惯性的mapper 扫描
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.yml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
配置文件
spring:
application:
name: dynamic_test
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
one:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
username: root
password: Xu666666
two:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true
username: root
password: Xu666666
initial-size: 1
min-idle: 1
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
mybatis:
mapper-locations: classpath:mapper/*.xml
构建配置文件
public interface DataSourceName {
String FIRST = "one";
String SECOND = "two";
}
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
@Configuration
public class DynamicDataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.druid.one")
public DataSource oneDataSource() {
return new DruidDataSource();
}
@Bean
@ConfigurationProperties("spring.datasource.druid.two")
public DataSource twoDataSource() {
return new DruidDataSource();
}
@Bean
@Primary
public DynamicDataSource dataSource(DataSource oneDataSource, DataSource twoDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>(2);
// 每个key对应一个数据源
targetDataSources.put(DataSourceName.FIRST, oneDataSource);
targetDataSources.put(DataSourceName.SECOND, twoDataSource);
return new DynamicDataSource(oneDataSource, targetDataSources);
}
}
aop 进行注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DSAnnotation {
String dsName() default DataSourceName.FIRST;
}
@Aspect
@Component
@Order(value = 1)
public class DSAspect {
@Pointcut("@annotation(com.demedb.database.annotation.DSAnnotation)")
public void dataSourcePointCut() {
}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
// 在执行方法之前设置使用哪个数据源
DSAnnotation ds = method.getAnnotation(DSAnnotation.class);
if (ds == null) {
DynamicDataSource.setDataSource(DataSourceName.FIRST);
} else {
DynamicDataSource.setDataSource(ds.dsName());
}
try {
return point.proceed();
} finally {
DynamicDataSource.clearDataSource();
}
}
}
测试
@Autowired
private TestService testService;
@GetMapping("/list")
public String selectAll(){
List<TestModel> ls = testService.selectAll();
System.out.println(ls);
return ls.toString();
}
@DSAnnotation(dsName = DataSourceName.SECOND)
@GetMapping("/list2")
public String selectAll02(){
List<TestModel> ls = testService.selectAll();
System.out.println(ls);
return ls.toString();
}