springboot多数据源使用

多数据源

一、多数据源的典型使用场景
在实际开发中,经常可能遇到在一个应用中可能需要访问多个数据库的情况。以下是两种典型场景:
1 业务复杂(数据量大)

数据分布在不同的数据库中,数据库拆了, 应用没拆。 一个公司多个子项目,各用各的数据库,涉及数据共享…
在这里插入图片描述

2 读写分离
为了解决数据库的读性能瓶颈(读比写性能更高, 写锁会影响读阻塞,从而影响读的性能)。 很多数据库拥主从架构。也就是,一台主数据库服务器,是对外提供增删改业务的生产服务器;另一(多)台从数据库服务器,主要进行 读的操作。
可以通过中间件(ShardingSphere、mycat、mysql-proxy 、TDDL …), 但是有一些规模较小的公司,没有专门的中间件团队搭建读写分 离基础设施,因此需要业务开发人员自行实现读写分离。
在这里插入图片描述
二、 如何实现多数据源
原理:
对于大多数的java应用,都使用了spring框架,spring-jdbc模块提供了AbstractRoutingDataSource,其内部可以包含了多个 DataSource,然后在运行时来动态的访问哪个数据库。这种方式访问数据库的架构图如下所示:
在这里插入图片描述
应用直接操作的是AbstractRoutingDataSource的实现类,告诉AbstractRoutingDataSource访问哪个数据库,然后由 AbstractRoutingDataSource从事先配置好的数据源(ds1、ds2)选择一个,来访问对应的数据库。
在这里插入图片描述
1.当执行数据库持久化操作,只要集成了Spring就一定会通过DataSourceUtils获取Connection
2. 通过Spring注入的DataSource获取Connection 即可执行数据库操作
所以思路就是:只需配置一个实现了DataSource的Bean, 然后根据业务动态提供Connection即可 3.其实Spring已经提供一个DataSource实现类用于动态切换数据源——AbstractRoutingDataSource 4.分析AbstractRoutingDataSource即可实现动态数据源切换:

2.1、通过AbstractRoutingDataSource实现动态数据源
通过这个类可以实现动态数据源切换。如下是这个类的成员变量

	private Map<Object, Object> targetDataSources;
    private Object defaultTargetDataSource;
  	private Map<Object, DataSource>  resolvedDataSources;

targetDataSources保存了key和数据库连接的映射关系
defaultTargetDataSource标识默认的连接 resolvedDataSources这个数据结构是通过targetDataSources构建而来,存储结构也是数据库标识和数据源的
映射关系

而AbstractRoutingDataSource实现了InitializingBean接口,并实现了afterPropertiesSet方法。afterPropertiesSet方法 是初始化bean的时候执行,通常用作数据初始化。
resolvedDataSources就是在这里赋值

在这里插入图片描述
5.so! 我们只需创建AbstractRoutingDataSource实现类DynamicDataSource然后 始化targetDataSources和key为 数据源标识(可以是字符串、枚举、都行,因为标识是Object)、defaultTargetDataSource即可
6.后续当调用AbstractRoutingDataSource.getConnection 会接着调用提供的模板方法:
determineTargetDataSource
7.通过determineTargetDataSource该方法返回的数据库标识 从resolvedDataSources 中拿到对应的数据源
8.so!我们只需DynamicDataSource中实现determineTargetDataSource为其提供一个数据库标识

总结: 在整个代码中我们只需做4件大事:
1.定义AbstractRoutingDataSource实现类DynamicDataSource
2.初始化时为targetDataSources设置 不同数据源的DataSource和标识、及defaultTargetDataSource
3.在determineTargetDataSource中提供对应的数据源标识即可 4、切换数据源识即

什么到这还不会? 附上代码:

  1. 配置多数据源 和 AbstractRoutingDataSource的自定义实现类:DynamicDataSource
    配置多数据
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    DynamicDataSource 代码:

    1 public class DynamicDataSource extends AbstractRoutingDataSource {
    2
    3 /**
    4 * ThreadLocal 用于提供线程局部变量,在多线程环境可以保证各个线程里的变量独立于其它线程里的变量。
    5 * 也就是说 ThreadLocal 可以为每个线程创建一个【单独的变量副本】,相当于线程的 private static 类型变量。
    6 /
    7 private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>();
    8
    9 /
    *
    10 * 决定使用哪个数据源之前需要把多个数据源的信息以及默认数据源信息配置好
    11 *
    12 * @param defaultTargetDataSource 默认数据源
    13 * @param targetDataSources 目标数据源
    14 */
    15 public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
    16 super.setDefaultTargetDataSource(defaultTargetDataSource);
    17 super.setTargetDataSources(targetDataSources);
    18 super.afterPropertiesSet();
    19 }
    20
    21 @Override
    22 protected Object determineCurrentLookupKey() {
    23 return getDataSource();
    24 }
    25
    26 public static void setDataSource(String dataSource) {
    27 CONTEXT_HOLDER.set(dataSource);
    28 }
    29
    30 public static String getDataSource() {
    31 return CONTEXT_HOLDER.get();
    32 }
    33
    34

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼香Ross

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值