SoFunction
Updated on 2025-04-04

Solution to implement multi-data source connection and switching in SpringBoot

introduction

In Spring Boot, it is a common practice to implement multi-data source connections through AbstractRoutingDataSource. This technology allows you to dynamically switch data sources at runtime, thus supporting operations on multiple databases. In Spring Boot, AbstractRoutingDataSource is configured and used to implement multi-data source connections.

1. Add dependencies

File dependencies, such as Spring Data JPA and database drivers:

<dependencies>
    <dependency>
        <groupId></groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!-- Other dependencies -->
</dependencies>

2. Configure data source properties

existorConfigure information for multiple data sources in it. For example:

spring:
  datasource:
    primary:
      url: jdbc:mysql://localhost:3306/primary_db
      username: root
      password: root
      driver-class-name: 
    secondary:
      url: jdbc:mysql://localhost:3306/secondary_db
      username: root
      password: root
      driver-class-name: 

3. Create a data source configuration class

Create two data source configuration classes that are used to configure the primary and secondary data sources respectively.

@Configuration
public class DataSourceConfig {

    @Bean(name = "primaryDataSource")
    @ConfigurationProperties(prefix = "")
    public DataSource primaryDataSource() {
        return ().build();
    }

    @Bean(name = "secondaryDataSource")
    @ConfigurationProperties(prefix = "")
    public DataSource secondaryDataSource() {
        return ().build();
    }
}

4. Create a custom data source routing class

ExtendedAbstractRoutingDataSourceclass and dynamically return the data source according to context information.

public class DynamicRoutingDataSource extends AbstractRoutingDataSource {

    @Override
    protected Object determineCurrentLookupKey() {
        return ();
    }
}

5. Create a data source context holder

Used to set and get the current data source type at runtime.

public class DataSourceContextHolder {

    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. Configure multiple data sources

Configure the data source into the Spring context and specify the default data source.

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    basePackages = "",
    entityManagerFactoryRef = "entityManagerFactory",
    transactionManagerRef = "transactionManager"
)
public class DataSourceRoutingConfig {

    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;

    @Autowired
    @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;

    @Bean
    public DataSource dataSource() {
        DynamicRoutingDataSource routingDataSource = new DynamicRoutingDataSource();
        Map<Object, Object> targetDataSources = new HashMap<>();
        ("primary", primaryDataSource);
        ("secondary", secondaryDataSource);
        (targetDataSources);
        (primaryDataSource);
        return routingDataSource;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(dataSource())
                .packages("")
                .persistenceUnit("multiple-pu")
                .build();
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

7. Use AOP to switch data sources

Set the data source type before the method is executed through AOP and clear after the method is executed.

@Aspect
@Component
public class DataSourceAspect {

    @Before("@annotation(targetDataSource)")
    public void changeDataSource(JoinPoint point, TargetDataSource targetDataSource) throws Throwable {
        (());
    }

    @After("@annotation(targetDataSource)")
    public void clearDataSource(JoinPoint point, TargetDataSource targetDataSource) {
        ();
    }
}

Custom annotationsTargetDataSource

@Target({, })
@Retention()
public @interface TargetDataSource {
    String value();
}

8. Switch data sources with custom annotations

Use on methods or classes that require a specific data source@TargetDataSourceannotation.

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @TargetDataSource("primary")
    public User findUserById(Long id) {
        return (id).orElse(null);
    }

    @TargetDataSource("secondary")
    public User findUserBySecondaryId(Long id) {
        // Assume that the secondary database has a similar table structure        return (id).orElse(null);
    }
}

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