最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot動態(tài)配置數據源的三種實現方式

 更新時間:2025年08月13日 10:17:11   作者:Best_Liu~  
本文介紹了Spring Boot動態(tài)數據源的三種實現方式:通過配置文件設置數據源,自定義DynamicDataSource繼承AbstractRoutingDataSource實現動態(tài)切換,利用ThreadLocal管理數據源標識,并結合AOP控制切換邏輯,同時需整合MyBatis-Plus配置,需要的朋友可以參考下

一、Apache Druid方式

1、配置文件

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    master:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&generateSimpleParameterMetadata=true&autoReconnect=true&useSSL=true
      username: root
      password: root3306
    slave:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&generateSimpleParameterMetadata=true&autoReconnect=true&useSSL=true
      username: root
      password: root3306
    druid-pool:
      #連接池的最大數據庫連接數。設為0表示無限制
      max-active: 20
      #初始化數量
      initial-size: 2
      #最大建立連接等待時間。如果超過此時間將接到異常。設為-1表示無限制
      max-wait: 60000
      #最小空閑連接:連接池中容許保持空閑狀態(tài)的最小連接數量,低于這個數量將創(chuàng)建新的連接
      min-idle: 2

2、配置數據源

配置數據源基本信息,并將所有數據源添加到動態(tài)數據源中進行進行管理

@Configuration
public class DynamicDataSourceConfig {
 
    @Value("${spring.datasource.type}")
    private Class<? extends DataSource> dataSourceType;
 
    @Value("${spring.datasource.druid-pool.initial-size}")
    private int initialSize;
    @Value("${spring.datasource.druid-pool.max-active}")
    private int maxActive;
    @Value("${spring.datasource.druid-pool.max-wait}")
    private int maxWait;
    @Value("${spring.datasource.druid-pool.min-idle}")
    private int minIdle;
 
    @Primary
    @Bean("masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        DruidDataSource druidDataSource = (DruidDataSource) DataSourceBuilder.create().type(dataSourceType).build();
        druidPoolConfig(druidDataSource);
        return druidDataSource;
    }
 
    @Bean("slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        DruidDataSource druidDataSource = (DruidDataSource) DataSourceBuilder.create().type(dataSourceType).build();
        druidPoolConfig(druidDataSource);
        return druidDataSource;
    }
 
    private void druidPoolConfig(DruidDataSource druidDataSource) {
        druidDataSource.setMaxActive(maxActive);
        druidDataSource.setMaxWait(maxWait);
        druidDataSource.setInitialSize(initialSize);
        druidDataSource.setMinIdle(minIdle);
    }
 
    @Bean("dataSource")
    @DependsOn({"masterDataSource", "slaveDataSource"})
    public DataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("slaveDataSource") DataSource slaveDataSource) {
        Map<Object, Object> dataSourceMap = new HashMap<>();
        dataSourceMap.put("masterDataSource", masterDataSource);
        dataSourceMap.put("slaveDataSource", slaveDataSource);
        DynamicDataSourceContextHolder.dataSourceNames.add("masterDataSource");
        DynamicDataSourceContextHolder.dataSourceNames.add("slaveDataSource");
        // 設置動態(tài)數據源
        return new DynamicDataSource(masterDataSource, dataSourceMap);
    }
}
public class DynamicDataSource extends AbstractRoutingDataSource {
 
    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
    }
 
    @Override
    public Object determineCurrentLookupKey() {
        return DynamicDataSourceContextHolder.getDataSource();
    }
}

自定義DynamicDataSouce并繼承AbstractRoutingDataSource 。AbstractRoutingDataSource 是 Spring 框架中用于實現動態(tài)數據源路由的一個抽象類。它通過實現數據源的動態(tài)切換來支持多數據源的應用場景。

AbstractRoutingDataSource 的核心原理是通過一個線程本地變量(ThreadLocal)來保存當前使用的數據源標識,然后在每次獲取連接時,根據這個標識來決定使用哪個數據源。

主要方法包括:

1)determineCurrentLookupKey():這是一個抽象方法,需要子類實現。它用于確定當前使用的數據源標識。根據返回的標識,AbstractRoutingDataSource 會從預先配置的數據源中選擇對應的數據源。

2)setTargetDataSources():用于設置數據源的映射關系。這個方法接受一個 Map<Object, Object> 類型的參數,鍵為數據源標識,值為具體的數據源對象。

3)setDefaultTargetDataSource():用于設置默認的數據源。如果沒有找到匹配的數據源標識,就會使用默認的數據源。

4)afterPropertiesSet():檢查配置,確保 targetDataSources 和 defaultTargetDataSource 屬性已被設置;初始化映射,將指定的默認數據源和目標數據源映射解析并存儲到相應的內部變量中。

public class DynamicDataSourceContextHolder {
    private static final ThreadLocal<String> DATASOURCE_CONTEXT_HOLDER = new ThreadLocal<>();
    /**
     * 管理全部數據源
     */
    public static List<String> dataSourceNames = new ArrayList<>();
 
    /**
     * 判斷是否存在指定數據源
     */
    public static boolean containsDataSource(String dataSourceName) {
        return dataSourceNames.contains(dataSourceName);
    }
    /**
     * 設置當前數據源
     */
    public static void setDataSource(String dataSourceName) {
        DATASOURCE_CONTEXT_HOLDER.set(dataSourceName);
    }
    /**
     * 獲取當前數據源
     */
    public static String getDataSource() {
        return DATASOURCE_CONTEXT_HOLDER.get();
    }
    /**
     * 清除數據源
     */
    public static void clear() {
        DATASOURCE_CONTEXT_HOLDER.remove();
    }
}

ThreadLocal是Java中的一個工具類,能夠為每個線程提供一個獨立的變量副本,從而實現線程隔離。利用ThreadLocal管理當前使用的數據源,DynamicDataSourceContextHolder可以在不同的線程間隔離數據源的使用,實現數據源的動態(tài)切換。

如果整合使用了Mybatis-Plus,則還需要添加Mybatis-Plus的相關配置,否則會報錯,如下所示

@Configuration
@MapperScan(basePackages = {"com.practice.mapper"}, sqlSessionTemplateRef = "sqlTemplateDefault")
public class MybatisConfig {
    @Bean(name = "sqlFactoryDefault")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("dynamicDataSource") DataSource dynamicDataSource)
            throws Exception {
        MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
        factoryBean.setDataSource(dynamicDataSource);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        factoryBean.setMapperLocations(resolver.getResources("classpath*:mapper/*/*.xml"));
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisConfiguration.setLogImpl(StdOutImpl.class);
        factoryBean.setConfiguration(mybatisConfiguration);
        return factoryBean.getObject();
    }
 
    @Bean(name = "sqlTemplateDefault")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlFactoryDefault") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

3、利用AOP動態(tài)切換

自定義數據源標識注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DS {
    String value() default "masterDataSource";
}

利用AOP實現動態(tài)切換數據源

@Component
@Aspect
@Slf4j
public class DynamicDataSourceAspect {
    private static final String DEFAULT_DATASOURCE = "masterDataSource";
 
    @Pointcut("@annotation(com.practice.annotation.DS)")
    public void dsPointCut() {}
 
    @Before("dsPointCut() && @annotation(ds)")
    public void changeDataSource(JoinPoint joinPoint, DS ds) {
        String dataSourceName = ds.value();
        if (DynamicDataSourceContextHolder.containsDataSource(dataSourceName)) {
            DynamicDataSourceContextHolder.setDataSource(dataSourceName);
            log.info("切換到數據源:{}", dataSourceName);
        } else {
            log.error("數據源不存在:{}", dataSourceName);
        }
    }
 
    @After("@annotation(ds)")
    public void clearDataSource(JoinPoint joinPoint, DS ds) {
        DynamicDataSourceContextHolder.clear();
    }
}

以上就是SpringBoot動態(tài)配置數據源的三種實現方式的詳細內容,更多關于SpringBoot動態(tài)配置數據源的資料請關注腳本之家其它相關文章!

相關文章

  • 淺談Java中的interface應用與面向接口編程

    淺談Java中的interface應用與面向接口編程

    這篇文章主要介紹了淺談Java中的interface應用與面向接口編程,Java的關鍵字interface應用,一個接口,多個實現類,面向接口編程,把業(yè)務邏輯線提取出來作為接口,具體的業(yè)務實現通過該接口的實現類來完成,需要的朋友可以參考下
    2023-10-10
  • java線程池ThreadPoolExecutor實現原理詳解

    java線程池ThreadPoolExecutor實現原理詳解

    這篇文章主要介紹了java線程池ThreadPoolExecutor實現原理詳解,ThreadPoolExecutor是線程池實現類,會動態(tài)創(chuàng)建多個線程,并發(fā)執(zhí)行提交的多個任務,需要的朋友可以參考下
    2023-12-12
  • SpringBoot內嵌tomcat處理有特殊字符轉義的問題

    SpringBoot內嵌tomcat處理有特殊字符轉義的問題

    這篇文章主要介紹了SpringBoot內嵌tomcat處理有特殊字符轉義的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Kotlin協程與并發(fā)深入全面講解

    Kotlin協程與并發(fā)深入全面講解

    Android官方對協程的定義-協程是一種并發(fā)設計模式,您可以在Android平臺上使用它來簡化異步執(zhí)行的代碼。協程是在版本1.3中添加到Kotlin的,它基于來自其他語言的既定概念
    2022-11-11
  • Java中的synchronized關鍵字全解析

    Java中的synchronized關鍵字全解析

    synchronized是Java中用于解決并發(fā)問題的核心關鍵字,通過確保多個線程對共享資源的互斥訪問,來避免線程安全問題,synchronized具有原子性、可見性、有序性和可重入性等特性,本文給大家介紹Java中的synchronized關鍵字相關,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • Spring的IOC容器實例化bean的方式總結

    Spring的IOC容器實例化bean的方式總結

    IOC容器實例化bean的三種方式:構造方法、靜態(tài)工廠、實例工廠,本文將通過代碼示例給大家詳細講解一下這三種方式,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01
  • java socket大數據傳輸丟失問題及解決

    java socket大數據傳輸丟失問題及解決

    這篇文章主要介紹了java socket大數據傳輸丟失問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • redis redisson 集合的使用案例(RList、Rset、RMap)

    redis redisson 集合的使用案例(RList、Rset、RMap)

    這篇文章主要介紹了redis redisson 集合的使用案例(RList、Rset、RMap),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Mybatis批量刪除數據操作方法

    Mybatis批量刪除數據操作方法

    MyBatis的作用我想不用多說,今天說說MyBatis中的批量刪除操作。 非常不錯,感興趣的朋友一起看看吧
    2016-09-09
  • JavaEE實現前后臺交互的文件上傳與下載

    JavaEE實現前后臺交互的文件上傳與下載

    這篇文章主要介紹了JavaEE實現前后臺交互的文件上傳與下載,分享相關技術,實現文件上傳下載功能,需要的朋友可以參考下
    2015-11-11

最新評論

来凤县| 嵊州市| 财经| 大关县| 威宁| 广昌县| 瓦房店市| 龙井市| 边坝县| 南和县| 松阳县| 通城县| 大足县| 潜山县| 灵宝市| 佛冈县| 渝北区| 海丰县| 新邵县| 汾阳市| 康定县| 县级市| 威远县| 醴陵市| 上蔡县| 漳平市| 康乐县| 宝鸡市| 甘泉县| 广汉市| 鲁山县| 福泉市| 遵化市| 彭州市| 栖霞市| 吉林市| 无棣县| 保山市| 台东县| 汕头市| 凌源市|