在 SpringBoot 项目中如何动态切换数据源、数据库?(可直接CV)
如果服务器搭建的是一主多从多个mysql数据源,主服务器用来读。从服务器用来写。此时你在代码层面用注解指定了一个增删改方法到从数据源,但是碰巧此时从数据源失效了,那么就会自动的切换到其它服务器。
前言
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
本文参考若依源码,介绍了如何在SpringBoot项目中使用AOP和自定义注解实现MySQL主从数据库的动态切换,当从库故障时,能自动切换到主库,确保服务的高可用性。
实现效果:
如果服务器搭建的是一主多从多个mysql数据源,主服务器用来读。从服务器用来写。此时你在代码层面用注解指定了一个增删改方法到从数据源,但是碰巧此时从数据源失效了,那么就会自动的切换到其它服务器。
为什么要切换数据源,有哪些应用场景?
动态切换数据源通常是为了满足以下需求:
读写分离:在数据库架构中,为了提高性能和可用性,常常使用主从复制的方式。主数据库处理写操作,而从数据库处理读操作。动态切换数据源可以在不同的操作中使用不同的数据库,以达到优化性能的目的。多租户架构:在SaaS(Software as a Service)应用中,不同的租户可能需要操作不同的数据库。动态数据源允许系统根据租户的身份来切换到对应的数据源。分库分表:在处理大规模数据时,可能会采用分库分表的策略来分散数据存储的压力。动态切换数据源可以在执行跨库或跨表操作时,根据需要切换到正确的数据源。环境隔离:在开发、测试和生产环境中,可能需要连接到不同的数据库。动态数据源可以在不同环境之间无缝切换,以确保数据的隔离和安全性。灵活的数据库管理:在复杂的业务场景下,可能需要根据不同的业务逻辑来选择不同的数据源。动态数据源提供了这种灵活性,允许开发者根据运行时的条件来选择最合适的数据源。故障转移和高可用性:当主数据库不可用时,动态切换数据源可以自动或手动切换到备用数据库,以保证服务的连续性和数据的可用性。如何切换数据源?
SpringBoot版本:3.0.4jdk版本:JDK171.pom文件
2.配置文件:application.yml、application-druid.yml
application.yml配置文件:
#application.yml server: port: 8000spring: profiles: active: druid
application-druid.yml配置文件:
# 数据源配置spring:datasource: type:com.alibaba.druid.pool.DruidDataSource driverClassName:com.mysql.cj.jdbc.Driver druid: # 主库数据源 master: url:jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username:root password:123456 # 从库数据源 slave: # 从数据源开关/默认关闭 enabled:true url:jdbc:mysql://localhost:3306/t_lyj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username:root password:123456 # 初始连接数 initialSize:5 # 最小连接池数量 minIdle:10 # 最大连接池数量 maxActive:20 # 配置获取连接等待超时的时间 maxWait:60000 # 配置连接超时时间 connectTimeout:30000 # 配置网络超时时间 socketTimeout:60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis:60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis:300000 # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis:900000
3、数据源名称枚举DataSourceType
/** * 数据源 * * @author ruoyi */public enum DataSourceType{ /** * 主库 */ MASTER, /** * 从库 */ SLAVE}
4、Bean工具类SpringUtils
@Componentpublicfinalclass SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware { /** Spring应用上下文环境 */ privatestatic ConfigurableListableBeanFactory beanFactory; privatestatic ApplicationContext applicationContext; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { SpringUtils.beanFactory = beanFactory; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringUtils.applicationContext = applicationContext; } /** * 获取对象 * * @param name * @return Object 一个以所给名字注册的bean的实例 * @throws BeansException * */ @SuppressWarnings("unchecked") publicstatic
5、多数据源切换注解DataSource
/** * 自定义多数据源切换注解 * * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准 * * @author lyj */@Target({ ElementType.METHOD, ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documented@Inheritedpublic @interface DataSource{ /** * 切换数据源名称 */ public DataSourceType value() default DataSourceType.MASTER;}
6、数据源解析配置类DruidConfig
@Configurationpublicclass DruidConfig { @Bean @ConfigurationProperties("spring.datasource.druid.master") public DataSource masterDataSource(DruidProperties druidProperties){ DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); return druidProperties.dataSource(dataSource); } @Bean @ConfigurationProperties("spring.datasource.druid.slave") @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true") public DataSource slaveDataSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); return druidProperties.dataSource(dataSource); } @Bean(name = "dynamicDataSource") @Primary public DynamicDataSource dataSource(DataSource masterDataSource) { Map
7、数据源注入核心类DynamicDataSource
/** * 动态数据源 * * @author lyj */publicclass DynamicDataSource extends AbstractRoutingDataSource { public DynamicDataSource(DataSource defaultTargetDataSource, Map
8、数据源切换处理类DynamicDataSourceContextHolder
/** * 数据源切换处理 * * @author lyj */publicclass DynamicDataSourceContextHolder{ publicstaticfinal Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class); /** * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本, * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 */ privatestaticfinal ThreadLocal
9、Aop切面类
@Aspect@Order(1)@Componentpublicclass DataSourceAspect { @Pointcut("@annotation(com.LYJ.study.DynamicDataSource.annocation.DataSource)" + "|| @within(com.LYJ.study.DynamicDataSource.annocation.DataSource)") public void dsPointCut(){} @Around("dsPointCut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ DataSource dataSource = getDataSource(joinPoint); if (dataSource != null){ DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name()); } try { return joinPoint.proceed(); } finally { // 销毁数据源 在执行方法之后 DynamicDataSourceContextHolder.clearDataSourceType(); } } /** * 获取需要切换的数据源 */ public DataSource getDataSource(ProceedingJoinPoint point) { MethodSignature signature = (MethodSignature) point.getSignature(); com.LYJ.study.DynamicDataSource.annocation.DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), com.LYJ.study.DynamicDataSource.annocation.DataSource.class); if (Objects.nonNull(dataSource)) { return dataSource; } return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class); }}
10、在业务中使用
图片
@Service@RequiredArgsConstructor@DataSource(value=DataSourceType.MASTER)//@DataSource(value=DataSourceType.SLAVE)publicclass UserServiceImpl extends ServiceImpl
我们在service、mapper的类和方法上使用都可以。
补充:有很多从数据源怎么办?
我们上面已经配置了一个从数据源了,接下来我们继续配置多个从数据源
首先在application-druid.yml文件添加新的数据源
图片
在枚举添加数据源名称
//如果配置多数据源,继续添加即可public enum DataSourceType{ /** * 主库 */ MASTER, /** * 从库 */ SLAVE, /** * 从库2 */ SLAVE2}
图片
如何切换数据库?
我们就以Oracle为例
在application-druid.yml添加
slave3: # 从数据源开关/默认关闭 enabled: true url: jdbc:oracle:thin:@127.0.0.1:1521:oracle username: root password: password
然后删除指定的mysql驱动,默认会自动寻找驱动

添加数据源和用法参考上面即可,都是一样的。
注意:在切换数据库时,因为mysql跟Oracle的sql语法有差别,启动时可能报错。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
2026 款 LG gram Pro 16/17 笔记本上市:重约 1.24~1.38kg,13199~13999 元
2026款LG gram Pro正式开售:极致轻薄的新标杆,这价格香吗? 关注高端轻薄型笔记本电脑市场的用户注意了,最新动态已经到来。2026款LG gram Pro系列笔记本现已全面上市发售,为追求极致便携性与强大性能兼顾的消费者提供了全新选择。具体来看,16英寸机型提供了经典的黑白两种配色,其中
4月1日服务升级 realme将全面接入OPPO售后服务
OPPO官方正式公告:2026年4月1日起,realme全面接入OPPO全国售后服务网络 重磅消息发布:长期保持独立运营的手机品牌realme,现已正式官宣回归OPPO体系,未来将作为其旗下子品牌,专注耕耘差异化细分市场。这一战略路径您是否感觉熟悉?事实上,它与一加手机此前的回归定位高度相似。此次深
技嘉AI TOP ATOM携手AIMA打造桌面级AI落地新范式
桌面级AI的实用化转型:从技术可行到场景赋能 随着生成式AI应用进入大规模实践阶段,桌面级人工智能设备正经历一场深刻的价值重塑。行业焦点已从早期的“能否本地运行大模型”转向更本质的命题:“如何深度融入真实工作场景并创造实际效能”。当前市场对数据主权、部署可控性及流畅交互体验的需求呈现爆发式增长。据统
OPPO K15 Pro超感潮流设计 人人都能个性定制
OPPO K12 Pro官图正式发布:模块化设计+RGB呼吸灯,打造个性化旗舰 据官方最新消息,OPPO K12 Pro系列手机已确认将于3月30日正式与大家见面。作为新一代性能潮流旗舰,该系列深度融合了强劲性能与个性化表达。从“新一代疾风散热引擎”到“颠覆性的潮流设计理念”等关键词不难看出,其旨在
vivo Pad6 Pro定档3月30日 4K超旗舰平板即将登场
vivo Pad6 Pro屏幕素质解析:4K原彩屏为何成最大亮点? 3月30日晚7点,vivo将正式发布旗下新一代高端安卓平板——vivo Pad6 Pro。作为定位旗舰市场的力作,该产品凭借多项行业领先配置,已在数码爱好者与高效能用户群体中积累了可观热度。 纵观其核心规格,最受瞩目的无疑是显示部分
- 日榜
- 周榜
- 月榜
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

