我们只需要配置五个文件,每个文件都很简单明了
application.yml
我们在这个文件里面配置多个数据源信息,注意给两个数据库设置别名:jc-db、xtg-db
spring:
datasource:
jc-db:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysq.......
username: ......
password: ......
driver-class-name: com.mysql.cj.jdbc.Driver
druid:
filters: stat,wall,logback
max-active: 100
initial-size: 1
max-wait: 60000
min-idle: 1
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
xtg-db:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql......
username: ......
password: ......
driver-class-name: com.mysql.cj.jdbc.Driver
druid:
filters: stat,wall,logback
max-active: 100
initial-size: 1
max-wait: 60000
min-idle: 1
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 1
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
DataSourceAspect.java
设置执行多数据源切换的切面信息
@Component
@Aspect
@Order(0)
public class DataSourceAspect {
//定义切点的位置,第一个* 表示 任意返回值后面是路径,最后一个*代表任意满足条件的方法(..)
//表示任意参数
@Pointcut("execution( * com.study.service.api.*.*.*(..))")
public void dataSource(){}
@Before(value = "dataSource()",argNames = "point")
public void changeDataSource(JoinPoint point){
String path = point.getSignature().getDeclaringTypeName();
DataSourceEnum[] values = DataSourceEnum.values();
DataSourceContextHolder.clearDataSource();
for (DataSourceEnum value : values) {
if (path.contains(value.getCode())){
DataSourceContextHolder.setDataSource(value.getCode());
}
}
}
@After("dataSource()")
public void clearDataSource(){
DataSourceContextHolder.clearDataSource();
}
}
DataSourceEnum.java
这个是多数据源的枚举类
public enum DataSourceEnum {
JCY_DB("jcDB", "jc数据库"),
XTGL_DB("xtgDB", "xtg数据库");
private String code;
private String desc;
DataSourceEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
DynamicDataSourceConfig.java
多数据源的基本配置文件
@Configuration
@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)
public class DynamicDataSourceConfig {
@Bean(name = "jcDB")
@ConfigurationProperties(prefix = "spring.datasource.jc-db")
public DataSource jcDB(){
return new DruidDataSource();
}
@Bean(name = "xtgDB")
@ConfigurationProperties(prefix = "spring.datasource.xtg-db")
public DataSource xtgDB(){
return new DruidDataSource();
}
@Primary
@Bean(name = "dynamicDataSource")
public DataSource dynamicDataSource(){
AbstractRoutingDataSource dynamicDataSource = new AbstractRoutingDataSource() {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
};
dynamicDataSource.setDefaultTargetDataSource(jcyDB());
HashMap<Object,Object> dataSourceMap = new HashMap<>();
dataSourceMap.put(DataSourceEnum.JC_DB.getCode(),jcDB());
dataSourceMap.put(DataSourceEnum.XTG_DB.getCode(),xtgDB());
dynamicDataSource.setTargetDataSources(dataSourceMap);
dynamicDataSource.afterPropertiesSet();
return dynamicDataSource;
}
}
DataSourceContextHolder.java
存放一些操作数据源的方法
public class DataSourceContextHolder {
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();
}
}
最后注意的是,第一个切面类定义的切面是:com.study.service.api下的数据库枚举类的code值命名的文件夹,在这里也就是com.study.service.api.jcDB和com.study.service.api.xtgDB。所以记得创建这两个文件夹以及下这两个文件夹下放对应数据库的service层