@@ -31,9 +31,12 @@ public class SpringBootDemoDynamicDatasourceApplication implements CommandLineRu | |||||
@Override | @Override | ||||
public void run(String... args) { | public void run(String... args) { | ||||
// 设置默认的数据源 | |||||
DatasourceConfigContextHolder.setDefaultDatasource(); | DatasourceConfigContextHolder.setDefaultDatasource(); | ||||
// 查询所有数据库配置列表 | |||||
List<DatasourceConfig> datasourceConfigs = configMapper.selectAll(); | List<DatasourceConfig> datasourceConfigs = configMapper.selectAll(); | ||||
System.out.println("加载其余数据源配置列表: " + datasourceConfigs); | System.out.println("加载其余数据源配置列表: " + datasourceConfigs); | ||||
// 将数据库配置加入缓存 | |||||
datasourceConfigs.forEach(config -> DatasourceConfigCache.INSTANCE.addConfig(config.getId(), config)); | datasourceConfigs.forEach(config -> DatasourceConfigCache.INSTANCE.addConfig(config.getId(), config)); | ||||
} | } | ||||
} | } |
@@ -4,7 +4,7 @@ import java.lang.annotation.*; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
* 默认数据源 | |||||
* 用户标识仅可以使用默认数据源 | |||||
* </p> | * </p> | ||||
* | * | ||||
* @author yangkai.shen | * @author yangkai.shen | ||||
@@ -37,7 +37,7 @@ public class DatasourceSelectorAspect { | |||||
} | } | ||||
/** | /** | ||||
* 前置通知 用于拦截操作 | |||||
* 前置操作,拦截具体请求,获取header里的数据源id,设置线程变量里,用于后续切换数据源 | |||||
*/ | */ | ||||
@Before("datasourcePointcut()") | @Before("datasourcePointcut()") | ||||
public void doBefore(JoinPoint joinPoint) { | public void doBefore(JoinPoint joinPoint) { | ||||
@@ -45,6 +45,7 @@ public class DatasourceSelectorAspect { | |||||
MethodSignature methodSignature = (MethodSignature) signature; | MethodSignature methodSignature = (MethodSignature) signature; | ||||
Method method = methodSignature.getMethod(); | Method method = methodSignature.getMethod(); | ||||
// 排除不可切换数据源的方法 | |||||
DefaultDatasource annotation = method.getAnnotation(DefaultDatasource.class); | DefaultDatasource annotation = method.getAnnotation(DefaultDatasource.class); | ||||
if (null != annotation) { | if (null != annotation) { | ||||
DatasourceConfigContextHolder.setDefaultDatasource(); | DatasourceConfigContextHolder.setDefaultDatasource(); | ||||
@@ -62,6 +63,9 @@ public class DatasourceSelectorAspect { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* 后置操作,设置回默认的数据源id | |||||
*/ | |||||
@AfterReturning("datasourcePointcut()") | @AfterReturning("datasourcePointcut()") | ||||
public void doAfter() { | public void doAfter() { | ||||
DatasourceConfigContextHolder.setDefaultDatasource(); | DatasourceConfigContextHolder.setDefaultDatasource(); | ||||
@@ -19,7 +19,7 @@ import javax.sql.DataSource; | |||||
* @date Created in 2019/9/4 16:20 | * @date Created in 2019/9/4 16:20 | ||||
*/ | */ | ||||
@Configuration | @Configuration | ||||
@MapperScan(basePackages = "com.xkcoding.dynamicdatasource.mapper", sqlSessionFactoryRef = "sqlSessionFactory") | |||||
@MapperScan(basePackages = "com.xkcoding.dynamic.datasource.mapper", sqlSessionFactoryRef = "sqlSessionFactory") | |||||
public class MybatisConfiguration { | public class MybatisConfiguration { | ||||
/** | /** | ||||
* 创建会话工厂。 | * 创建会话工厂。 | ||||
@@ -33,17 +33,24 @@ public class DynamicDataSource extends HikariDataSource { | |||||
return datasource.getConnection(); | return datasource.getConnection(); | ||||
} | } | ||||
/** | |||||
* 初始化数据源 | |||||
* @param id 数据源id | |||||
* @return 数据源 | |||||
*/ | |||||
private HikariDataSource initDatasource(Long id) { | private HikariDataSource initDatasource(Long id) { | ||||
HikariDataSource dataSource = new HikariDataSource(); | HikariDataSource dataSource = new HikariDataSource(); | ||||
// 判断是否是默认数据源 | |||||
if (DatasourceHolder.DEFAULT_ID.equals(id)) { | if (DatasourceHolder.DEFAULT_ID.equals(id)) { | ||||
// 默认数据源根据 application.yml 配置的生成 | |||||
DataSourceProperties properties = SpringUtil.getBean(DataSourceProperties.class); | DataSourceProperties properties = SpringUtil.getBean(DataSourceProperties.class); | ||||
dataSource.setJdbcUrl(properties.getUrl()); | dataSource.setJdbcUrl(properties.getUrl()); | ||||
dataSource.setUsername(properties.getUsername()); | dataSource.setUsername(properties.getUsername()); | ||||
dataSource.setPassword(properties.getPassword()); | dataSource.setPassword(properties.getPassword()); | ||||
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); | dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); | ||||
} else { | } else { | ||||
// 获取数据库的配置 | |||||
// 不是默认数据源,通过缓存获取对应id的数据源的配置 | |||||
DatasourceConfig datasourceConfig = DatasourceConfigCache.INSTANCE.getConfig(id); | DatasourceConfig datasourceConfig = DatasourceConfigCache.INSTANCE.getConfig(id); | ||||
if (datasourceConfig == null) { | if (datasourceConfig == null) { | ||||
@@ -55,6 +62,7 @@ public class DynamicDataSource extends HikariDataSource { | |||||
dataSource.setPassword(datasourceConfig.getPassword()); | dataSource.setPassword(datasourceConfig.getPassword()); | ||||
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); | dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); | ||||
} | } | ||||
// 将创建的数据源添加到数据源管理器中,绑定当前线程 | |||||
DatasourceHolder.INSTANCE.addDatasource(id, dataSource); | DatasourceHolder.INSTANCE.addDatasource(id, dataSource); | ||||
return dataSource; | return dataSource; | ||||
} | } | ||||
@@ -2,6 +2,7 @@ package com.xkcoding.dynamic.datasource.mapper; | |||||
import com.xkcoding.dynamic.datasource.config.MyMapper; | import com.xkcoding.dynamic.datasource.config.MyMapper; | ||||
import com.xkcoding.dynamic.datasource.model.User; | import com.xkcoding.dynamic.datasource.model.User; | ||||
import org.apache.ibatis.annotations.Mapper; | |||||
/** | /** | ||||
* <p> | * <p> | ||||
@@ -11,5 +12,6 @@ import com.xkcoding.dynamic.datasource.model.User; | |||||
* @author yangkai.shen | * @author yangkai.shen | ||||
* @date Created in 2019/9/4 16:49 | * @date Created in 2019/9/4 16:49 | ||||
*/ | */ | ||||
@Mapper | |||||
public interface UserMapper extends MyMapper<User> { | public interface UserMapper extends MyMapper<User> { | ||||
} | } |