SoFunction
Updated on 2025-03-04

Spring Boot Solution to implement multi-data source connection and switching

Preface

Implementing multi-data source connection and switching in Spring Boot can be achieved through the following solutions, depending on the project's requirements, database usage patterns and management complexity. The following is a common implementation of multi-data source switching, using AbstractRoutingDataSource to dynamically select data sources.

1. Multi-data source configuration and switching scheme

In a multi-data source scenario, there are usually the following steps:

  • Configure multiple data sourcesDataSource bean。
  • useAbstractRoutingDataSourceTo dynamically switch data sources.
  • useThreadLocalStores the current database type or data source identifier.
  • Configure the logic of data source switching, such as selecting different data sources based on the current user, request path, service identity, etc.

2. Implementation steps

1. Create multipleDataSourceConfiguration class

First, create a separate configuration class for each data source, usually you willorConfigure the connection information for each data source in the

spring:
  datasource:
    # Default data source configuration    primary:
      url: jdbc:mysql://localhost:3306/primary_db
      username: root
      password: password
      driver-class-name: 
      hikari:
        maximum-pool-size: 10
    # Second data source configuration    secondary:
      url: jdbc:mysql://localhost:3306/secondary_db
      username: root
      password: password
      driver-class-name: 
      hikari:
        maximum-pool-size: 10

2. CreateDataSourceConfiguration class

@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
    @Bean(name = "primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix = "")
    public DataSource primaryDataSource() {
        return ().build();
    }
    @Bean(name = "secondaryDataSource")
    @ConfigurationProperties(prefix = "")
    public DataSource secondaryDataSource() {
        return ().build();
    }
}

3. Create dynamic data source routing class

AbstractRoutingDataSourceAllows us to dynamically select data sources based on certain conditions at runtime.

@Configuration
public class DynamicDataSourceConfig {
    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;
    @Autowired
    @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;
    @Bean
    public DataSource dataSource() {
        // Create a routing data source        DynamicDataSource dataSource = new DynamicDataSource();
        (primaryDataSource); // Default data source        Map<Object, Object> targetDataSources = new HashMap<>();
        ("primary", primaryDataSource);
        ("secondary", secondaryDataSource);
        (targetDataSources);
        return dataSource;
    }
}

4. ImplementationDynamicDataSourcekind

DynamicDataSourceIt is inherited fromAbstractRoutingDataSource, it passesdetermineCurrentLookupKey()Method to dynamically determine the current data source.

public class DynamicDataSource extends AbstractRoutingDataSource {
    // Get the current database identity from ThreadLocal    @Override
    protected Object determineCurrentLookupKey() {
        return ();
    }
}

5. CreateDataSourceContextHolderTo store the current data source identifier

useThreadLocalto maintain the database identity of the current thread to switch between different data sources.

public class DataSourceContextHolder {
    // Use ThreadLocal to store the data source identity of the current thread    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    public static void setDataSourceType(String dataSourceType) {
        (dataSourceType);
    }
    public static String getDataSourceType() {
        return ();
    }
    public static void clearDataSourceType() {
        ();
    }
}

6. Switch data sources in AOP mode

In order to dynamically switch data sources at runtime, AOP facets are usually used to intercept method execution and specify data sources.

@Aspect
@Component
public class DataSourceAspect {
    // Specify which data source to use through annotation    @Before("@annotation(dataSource)")
    public void switchDataSource(DataSourceType dataSource) {
        // Switch data source        (());
    }
    @After("@annotation(dataSource)")
    public void clearDataSource(DataSourceType dataSource) {
        // Clean up the data source identifier to avoid affecting other threads        ();
    }
}

7. Custom annotations to specify the data source

Create a custom annotationDataSourceType, used to specify the data source to be used when the current method is executed.

@Target()
@Retention()
public @interface DataSourceType {
    String value() default "primary";  // Data source identification, primary data source is used by default}

8. Specify data source using annotations at the Service layer

In the Service layer, you can use the@DataSourceTypeAnnotation to specify different methods to use different data sources.

@Service
public class UserService {
    @DataSourceType("primary")
    public List<User> getPrimaryUsers() {
        // Query the main database        return ();
    }
    @DataSourceType("secondary")
    public List<User> getSecondaryUsers() {
        // Query the database        return ();
    }
}

Summarize

  • Data source configuration: Configure each data sourceDataSource Bean。
  • Dynamic data source routing:useAbstractRoutingDataSourceto achieve dynamic switching of data sources.
  • ThreadLocal Storage:useThreadLocalStores and gets the data source identity of the current thread.
  • AOP switches data source: Use AOP to intercept methods and switch data sources.
  • Annotation method Specify the data source: Use custom annotations to specify the specific data source used by the method.

This method is relatively flexible and can select different data sources according to business needs during operation. It is suitable for scenarios with multiple data sources, especially complex application scenarios such as library division and table division, read and write separation.

This is the article about Spring Boot implementing multi-data source connection and switching. For more related Spring Boot multi-data source connection and switching, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!