Spring原生支持多数据源动态切换,继承AbstractRoutingDataSource类重写determineCurrentLookupKey方法即可,为了方便切换可通过切面拦截自定义注解实现,代码如下:
1、SpringBoot使用Druid配置多数据源
spring:
#出现错误时, 直接抛出异常(便于异常统一处理,否则捕获不到404)
mvc:
throw-exception-if-no-handler-found: true
view:
prefix: classpath:/static/
suffix: .html
static-path-pattern: /**
resources:
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/templates/
thymeleaf:
prefix: classpath:/templates/
suffix: .html
encoding: utf-8
cache: false
mode: LEGACYHTML5
enabled: true
http:
encoding:
force: true
charset: UTF-8
force-request: true
enabled: true
datasource:
#配置DruidDatasouce连接池
type: com.alibaba.druid.pool.DruidDataSource
druid:
#连接数据库
driver-class-name: oracle.jdbc.driver.OracleDriver
#druid配置详情信息
max-active: 100 #最大连接数
initial-size: 1 #初始化连接数
max-wait: 60000 #获取最大等待时间
min-idle: 1 #最小连接数
validation-query: select * from dual
time-between-eviction-runs-millis: 60000 #一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 300000 #间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
pool-prepared-statements: false #是否缓存preparedStatement 在mysql的环境下建议关闭 因为对数据库性能消耗大
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
filters: stat,wall #配置监控统计拦截的filters,去掉后监控界面SQL无法进行统计,'wall'用于防火墙
stat-view-servlet:
url-pattern: /druid/*
druidDataSource1:
url: jdbc:oracle:thin:@localhost:1521:orcl
username: rim
password: rim
druidDataSource2:
url: jdbc:oracle:thin:@localhost:1521:orcl
username: rim
password: rim
druidDataSource3:
url: jdbc:oracle:thin:@localhost:1521:orcl
username: rim
password: rim
2、用于声明数据源的自定义注解TargetDataSource
package com.bsoft.core.datasource;
import com.bsoft.commons.constant.DataSourceKey;
import java.lang.annotation.*;
/**
* @author :Liujian
* @date :2019/11/15 16:48
* @description:自定义DataSource注解
* @version:
*/
@Target({
ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDataSource {
DataSourceKey value() default DataSourceKey.FIRST;
}
3、定义继承AbstractRoutingDataSource类重写determineCurrentLookupKey方法用于实现数据源动态切换
package com.bsoft.core.datasource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* @author :Liujian
* @date :2019/11/15 16:48
* @description:动态切换数据源
* @version:
*/
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
/**
* 获取与数据源相关的key
* 此key是Map<String, DataSource> resolvedDataSources 中与数据源绑定的key值
* 在通过determineTargetDataSource获取目标数据源时使用
*/
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceHolder.getDataSourceRouterKey();
}
}
4、定义数据源的连接字符串线程绑定DynamicDataSourceHolder
package com.bsoft.core.datasource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* @author :Liujian
* @date :2019/11/15 16:48
* @description:动态切换数据源
* @version:
*/
public class DynamicDataSourceHolder {
private static Logger logger = LoggerFactory.getLogger(DynamicDataSourceHolder.class);
/**
* 存储已经注册的数据源的key
*/
public static final List<Object> dataSourceKeys = new ArrayList<>();
/**
* 线程级别的私有变量
*/
private static final ThreadLocal<String> HOLDER = new ThreadLocal<>(