🍰SpringBoot下动态数据源切换
第一种:Mybatis-Plus的dynamic-datasource
Gitee地址:https://gitee.com/baomidou/dynamic-datasource-spring-boot-starter
要实现其实很简单,一个注解就可以了
1、创建两个一库,一样的表进行测试
2、搭建SpringBoot引入dynamic-datasource依赖
1 2 3 4 5 | <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.6.1</version> </dependency> |
3、修改SpringBoot配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | spring: datasource: dynamic: primary: master #设置默认的数据源或者数据源组,默认值即为master strict: false #严格匹配数据源,默认 false . true 未匹配到指定数据源时抛异常, false 使用默认数据源 datasource: master: url: jdbc:mysql: //localhost:3306/datasource-1?serverTimezone=UTC username: root password: xxx driver- class -name: com.mysql.cj.jdbc.Driver slave_1: url: jdbc:mysql: //localhost:3306/datasource-2?serverTimezone=UTC username: root password: xxx driver- class -name: com.mysql.cj.jdbc.Driver |
4、在方法上面添加@DS注解
第二种:使用Aop自己实现动态数据源的切换
Git地址:https://gitee.com/zhang-zhixi/dynamic-datasource-springboot
1、创建两个一库,一样的表进行测试
2、搭建SpringBoot环境
3、自定义切换数据源注解
1 2 3 4 5 6 | @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @ interface UsingDataSource { String value() default "" ; } |
4、编写存储自定义数据源的容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /** * @author zhixi * 存储数据源的key,使用线程安全方式进行添加数据源 */ public class DataSourceContextHolder { public static ThreadLocal<String> key = new ThreadLocal<>(); public static void setKey(String key) { DataSourceContextHolder.key. set (key); } public static String getKey() { return key. get (); } public static void clearKey() { key.remove(); } } |
5、确定使用的数据源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /** * @author zhixi * AbstractRoutingDataSource是一个抽象类,是Spring提供的用于动态数据源切换的类。 */ public class DynamicDataSource extends AbstractRoutingDataSource { /** * 查找哪个数据源的时候使用的key,该方法用于确定当前数据源 * @return 数据源 */ @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getKey(); } } |
6、重写Spring相关配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | package com.zhixi.config; import com.zhixi.datasource.DynamicDataSource; import org.mybatis.spring.SqlSessionFactoryBean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * @author zhixi * Spring相关配置 */ @Configuration public class DataSourceConfig { /** * 为每个数据源单独设置一个Bean * * @return 数据源1 */ @ConfigurationProperties( "datasource1" ) @Bean public DataSource dataSource1() { return DataSourceBuilder.create().build(); } /** * 为每个数据源单独设置一个Bean * * @return 数据源2 */ @Bean @ConfigurationProperties( "datasource2" ) public DataSource dataSource2() { return DataSourceBuilder.create().build(); } /** * 添加数据源 * * @return 自定义数据源 */ @Bean public DynamicDataSource dynamicDataSource() { Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put( "ds1" , dataSource1()); targetDataSources.put( "ds2" , dataSource2()); DynamicDataSource dynamicDataSource = new DynamicDataSource(); // 设置目标数据源 dynamicDataSource.setTargetDataSources(targetDataSources); // 设置默认目标数据源 dynamicDataSource.setDefaultTargetDataSource(dataSource1()); return dynamicDataSource; } /** * 使用DynamicDataSource作为数据源。 * * @param dynamicDataSource 数据源 * @return 配置好的SqlSessionFactoryBean对象,以便将其用作MyBatis框架的数据源。 * @throws IOException 异常 */ @Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DynamicDataSource dynamicDataSource) throws IOException { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); /*设置mybatis configuration 扫描路径 */ PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); //加载配置文件的地址 bean.setMapperLocations(resolver.getResources( "classpath:mapper/*.xml" )); bean.setDataSource(dynamicDataSource); return bean; } /** * 使用返回的数据源创建一个DataSourceTransactionManager对象。 * DataSourceTransactionManager是Spring提供的事务管理器,用于管理基于数据源的事务 * @ return 事务管理器 */ @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dynamicDataSource()); } } |
7、使用AOP,在方法调用前设置使用的数据源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package com.zhixi.datasource; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; /** * @author zhixi * Aop切面,对注解进行切面 */ @Aspect @Component public class DataSourceAspect { @Pointcut( "@annotation(com.zhixi.datasource.UsingDataSource)" ) public void checkPointCut() { } /** * 方法调用之前设置数据源 * @param usingDataSource 拿到注解的数据源的值 */ @Before( "checkPointCut() && @annotation(usingDataSource)" ) public void checkBefore(UsingDataSource usingDataSource) { // 添加数据源的key DataSourceContextHolder.setKey(usingDataSource.value()); } @After( "checkPointCut()" ) public void checkAfter() { DataSourceContextHolder.clearKey(); } } |
8、启动类配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /** * @author zhixi * exclude = {DataSourceAutoConfiguration.class}:排除SpringBoot自带的数据源配置 * EnableAspectJAutoProxy:启动动态代理 */ @EnableAspectJAutoProxy(proxyTargetClass = true , exposeProxy = true ) @MapperScan( "com.zhixi.mapper" ) @SpringBootApplication(exclude = {DataSourceAutoConfiguration. class }) public class DynamicDatasourceSpringbootApplication { public static void main(String[] args) { SpringApplication.run(DynamicDatasourceSpringbootApplication. class , args); } } |
9、编写Controller进行测试
分类:
微服务框架
标签:
mybatis-plus
, SpringBoot
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2021-02-02 如何将.class文件打成jar包
2021-02-02 IO流完成文件夹的拷贝与删除
2021-02-02 DDOS攻击
2021-02-02 定时器任务:Timer跟ScheduledExecutorService