springboot实现动态数据源切换
springboot+mybatis实现数据源的动态切换
springboot实现动态数据源切换
为什么需要切换数据源?
当数据量超过500万行时,数据库就要考虑分库分表和读写分离,有些业务背景需要动态切换数据库。
当controller层处理请求,需要在dao层代码执行之前能够将数据源换成我们想要执行操作的数据源。
底层原理
Springboot内置了一个AbstractRoutingDataSource,将所有数据源装入map,然后可以根据不同的key返回不同的数据源。当springboot开始执行连接数据库之前会执行determineCurrentLookupKey()方法,这个方法返回的数据将作为key去map中查找相应的数据源。
需求
根据不同的请求实现动态切换,查询不同的数据库。
实现步骤
-
创建springboot工程,准备 数据库 和 web相关的依赖
-
准备两个数据库的表,在项目中创建对应的pojo实体类
-
分别创建两个数据库对应的dao层、service层和controller层,核心启动类上需要添加包扫描MapperScan
-
准备相关的数据源配置信息,在application.properties文件中设置
-
创建数据源自动配置类,当容器启动时,创建对应的数据源bean对象
-
创建AbstractRoutingDataSource的子类,当springboot想要获取数据源对象时,会执行determinCurrentLookUpKey()方法,获取想要的数据源,所以需要重写这个方法
先将返回值写成固定字符串,后续实现动态获取key,再进行修改。 -
在数据源自动配置类中添加AbstractRoutingDataSource子类bean的注入,当AbstractRoutingDataSource想要获取数据源时,会从它的成员变量中存的数据源的map集合中获取,所以需要给它注入包含两个数据源的map集合
-
在核心启动类上需要添加@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class} ),排除默认的数据源
-
如何实现动态获取key?
每一个请求是一个单独的线程,将key存入当前线程的ThreadLocal里面。创建新的对象RoutingDataSourceContext,存在唯一的ThreadLocal对象,在构造函数中传入key,另外创建获取方法和关闭方法。
-
在重写的determinCurrentLookUpKey()方法中调用RoutingDataSourceContext动态获取key的方法
11. 在controller层发起请求时获取创建对应的RoutingDataSourceContext对象,传入对应的key,后续springboot找AbstractRoutingDataSource中的数据源时,就会由传入的key查找对应的map中的数据源。
-
测试
总结:
- 创建AbstractRoutingDataSource的子类,实现determinCurrentLookUpKey()方法
- 生成两个数据源bean对象需要配置进该子类bean对象中,当需要获取到数据源时,会从该对象的map中获取数据源
- 如何动态获取key --> 使用线程绑定的ThreadLocal,保证每次请求查找指定的数据源
更多推荐
所有评论(0)