SpringBoot中配置多数据源的方法详解
开始配置多数据源
首先我们需要先移除自动配置数据源,SpringBoot 的默认行为
DataSourceAutoConfiguration 是 SpringBoot 提供的自动配置类
@SpringBootApplication(scanBasePackages = "com", exclude = {DataSourceAutoConfiguration.class})
下面首先读取了默认数据源的信息,通过 getProperties() 封装成一个 Map 对象
定义了一个名为 dynamicDataSource 的 bean 是数据源路由器,它继承了 AbstractRoutingDataSource 类,我们可以根据规则选择要使用的数据源。
dataSource 方法接受一个 Map,并返回一个数据源,于是我们就创建了一个数据源
这段代码通过设置,配置了一个支持动态切换的数据源,默认使用 master,用于运行时动态切换数据源。
@Configuration @Slf4j public class DataSourceConfigurer { @Value("${spring.datasource.druid.master.url}") private String url; @Value("${spring.datasource.druid.master.username}") private String username; @Value("${spring.datasource.druid.master.password}") private String password; @Value("${spring.datasource.driverClassName}") private String driverClassName; /** * 获取数据源配置信息 * * @return 数据源配置信息 */ private Map<String, Object> getProperties() { Map<String, Object> map = new HashMap<>(); map.put("driverClassName", driverClassName); map.put("url", url); map.put("username", username); map.put("password", password); return map; } /** * 配置动态数据源 * * @return 动态数据源 */ @Bean("dynamicDataSource") public DynamicRoutingDataSource dynamicDataSource() { DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource(); // 创建数据源 DataSource dataSource = dynamicRoutingDataSource.dataSource(getProperties()); // 设置数据源映射 Map<Object, Object> dataSourceMap = new HashMap<>(1); dataSourceMap.put("default_db", dataSource); dynamicRoutingDataSource.setTargetDataSources(dataSourceMap); // 设置默认数据源 dynamicRoutingDataSource.setDefaultTargetDataSource(dataSource); return dynamicRoutingDataSource; } }
具体切换多数据源的逻辑 DynamicRoutingDataSource
多数据源切换的实现的关键是 AbstractRoutingDataSource
我们这里创建了一个 targetTargetDataSources 是一个 Map 存储数据源的数据,key 数据源的标识,value 是具体的数据源。通过 setTargetDataSources 可以设置数据源,在运行时,通过该方法切换。
通过 addDataSource 添加数据源,并通过 setTargetDataSources 使数据源生效。
existDataSource 是判断数据源是否存在
dataSource 这个是重要的方法,它是为数据源在druid 连接池中创建了资源,配置了数据源。
/** * 动态数据源 */ @Slf4j public class DynamicRoutingDataSource extends AbstractRoutingDataSource { private static Map<Object, Object> targetTargetDataSources = new ConcurrentHashMap<>(); @Override protected Object determineCurrentLookupKey() { // 每次连接数据库,都会去设置数据源 return DynamicDataSourceContextHolder.getDataSourceKey(); } // 设置targetDataSources并记录数据源(这里可以记录每个数据源的最近使用时间,可以做删除不经常使用的数据源) @Override public void setTargetDataSources(Map<Object, Object> targetDataSources) { super.setTargetDataSources(targetDataSources); super.afterPropertiesSet(); targetTargetDataSources = targetDataSources; } // 添加数据源 public void addDataSource(String tenant, Map<String, Object> dataSourceProperties) { targetTargetDataSources.put(tenant, dataSource(dataSourceProperties)); super.setTargetDataSources(targetTargetDataSources); afterPropertiesSet(); } // 判断是否存在数据源,存在直接取 public boolean existDataSource(String tenant) { return targetTargetDataSources.containsKey(tenant); } // 组装数据源 public DataSource dataSource(Map<String, Object> dataSourceProperties) { DataSource dataSource; try { dataSource = DruidDataSourceFactory.createDataSource(dataSourceProperties); } catch (Exception e) { log.error("dataSource: {}", e.getMessage()); throw new RuntimeException(); } return dataSource; } }
到此这篇关于SpringBoot中配置多数据源的方法详解的文章就介绍到这了,更多相关SpringBoot配置多数据源内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
mybatisplus where QueryWrapper加括号嵌套查询方式
这篇文章主要介绍了mybatisplus where QueryWrapper加括号嵌套查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。2022-01-01
最新评论