Spring Boot实现多数据源动态切换
Spring Boot应用中可以配置多个数据源,并根据注解灵活指定当前使用的数据源
步骤
- 在
application.yml
中配置数据源信息spring: datasource: ds1: driverClassName: org.sqlite.JDBC jdbcUrl: jdbc:sqlite::resource:ds1.db ds2: driverClassName: org.sqlite.JDBC jdbcUrl: jdbc:sqlite::resource:ds2.db
- 实现
DataSourceHolder
,将当前数据源的key保存在ThreadLocal
中public class DataSourceHolder { private static final ThreadLocal<String> HOLDER = new ThreadLocal<>(); public static void setDataSource(String ds) { HOLDER.set(ds); } public static String getDataSource() { return HOLDER.get(); } public static void clear() { HOLDER.remove(); } }
- 基于Spring Boot自带的
AbstractRoutingDataSource
实现DynamicDataSource
public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { // 获取代表当前数据源的key return DataSourceHolder.getDataSource(); } }
- 添加配置类
DataSourceConfig
,向容器中注入所有数据源,并注入一个DynamicDataSource
实例作为主数据源,并标注为Primary
@Configuration public class DataSourceConfig { /** * 数据源1配置 */ @Bean("ds1") @ConfigurationProperties("spring.datasource.ds1") public DataSource ds1() { return DataSourceBuilder.create().build(); } /** * 数据源2配置 */ @Bean("ds2") @ConfigurationProperties("spring.datasource.ds2") public DataSource ds2() { return DataSourceBuilder.create().build(); } /** * 动态数据源配置 */ @Bean @Primary public DataSource dynamicDataSource(@Qualifier("ds1") DataSource ds1, @Qualifier("ds2") DataSource ds2) { DynamicDataSource ds = new DynamicDataSource(); // 设置数据源映射关系 ds.setTargetDataSources(Map.of( "ds1", ds1, "ds2", ds2 )); // 设置默认数据源 ds.setDefaultTargetDataSource(ds1); return ds; } }
- 添加自定义注解
Db
,标注在方法上,指定方法内部执行时所使用的数据源@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Db { String value(); }
- 实现切面类
DynamicDataSourceAspect
,对所有标注了Db
注解的方法进行增强@Aspect @Component public class DynamicDataSourceAspect { /** * Mapper方法切面实现,对所有标注了Db注解的方法生效 */ @Around("@annotation(byx.test.Db)") public Object around(ProceedingJoinPoint jp) throws Throwable { // 获取方法上的Db注解 MethodSignature methodSignature = (MethodSignature) jp.getSignature(); Method method = methodSignature.getMethod(); Db db = method.getAnnotation(Db.class); try { // 方法执行前先设置当前数据源,再执行方法 DataSourceHolder.setDataSource(db.value()); return jp.proceed(); } finally { // 方法结束后清理当前数据源 DataSourceHolder.clear(); } } }
使用方法
@Mapper
public interface UserMapper {
@Select("SELECT * FROM users")
@Db("ds1")
List<User> listUsersFromDs1();
@Select("SELECT * FROM users")
@Db("ds2")
List<User> listUsersFromDs2();
}
完整代码
https://github.com/byx2000/spring-boot-learning/tree/master/dynamic-data-source
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgjfiaa
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13