Open In App

Configure Multiple DataSources in Spring Boot

Last Updated : 12 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Spring Boot is an extension for the Spring Java platform that prioritizes convention over configuration. To reduce configuration issues while developing Spring-based applications. To create a Spring Boot application that can interact with several databases, we must specify which configurations Spring Boot should use to determine when to run each source.

Steps to Configure Multiple DataSources in Spring Boot Application

Below are the steps to configure multiple data sources in a Spring Boot application.

Step 1: Add Dependencies

We can include the dependencies required for the H2 database in our pom.xml file if we want to establish more than one data source (the “todos” database is one example). This is how the H2 dependence may be added.

<dependencies>
<!-- Spring Boot Starter for Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Lombok for reducing boilerplate code -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring Boot Starter for testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Apache Commons DBCP for connection pooling -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>${commons.dbcp.version}</version>
</dependency>
</dependencies>

Step 2: DataSource Configuration for User Database

Using the DataSourceProperties class from Spring, which automatically loads database-related parameters like URL, username, and password depending on the prefix supplied in @ConfigurationProperties, we will load the configuration settings and utilize this to construct a DataSource bean.

Java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.DataSourceInitializationMode;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

import javax.sql.DataSource;

@Configuration
@EnableJpaRepositories(
        basePackages = "com.example.user.repository",
        entityManagerFactoryRef = "userEntityManagerFactory",
        dataSourceRef = "userDataSource",
        transactionManagerRef = "userTransactionManager"
)
public class UserDatasourceConfiguration {

    // Primary data source configuration
    @Primary
    @Bean(name = "userDataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create()
                .build();
    }

    // Configuration properties for the primary data source
    @Primary
    @Bean(name = "userProperties")
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    // EntityManagerFactory for the primary data source
    @Primary
    @Bean(name = "userEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            DataSource dataSource) {
        return builder
                .dataSource(dataSource)
                .packages("com.example.user.model")
                .persistenceUnit("user")
                .build();
    }
}

Step 3: Use Configuration Classes

Under Spring’s application context, we must declare numerous beans with distinct mappings in order to leverage various data sources.

Java
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TodoDatasourceConfiguration {

    // Configuring DataSourceProperties for the "todos" database
    @Bean
    @ConfigurationProperties("spring.datasource.todos")
    public DataSourceProperties todosDataSourceProperties() {
        return new DataSourceProperties();
    }
}

Step 4: Apply DataSourceProperties

The DataSourceProperties objects may be used to build the data sources.

Java
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    // Configuring DataSource for the "todos" database
    @Bean
    public DataSource todosDataSource() {
        return todosDataSourceProperties()
                .initializeDataSourceBuilder()
                .build();
    }

    // Configuring DataSource for the "topics" database
    @Bean
    public DataSource topicsDataSource() {
        return topicsDataSourceProperties()
                .initializeDataSourceBuilder()
                .build();
    }

    // Additional method to configure DataSourceProperties for "todos" database
    @Bean
    public DataSourceProperties todosDataSourceProperties() {
        return new DataSourceProperties();
    }

    // Additional method to configure DataSourceProperties for "topics" database
    @Bean
    public DataSourceProperties topicsDataSourceProperties() {
        return new DataSourceProperties();
    }
}

Step 5: Use Spring Data Java Database Connectivity

For every DataSource, we must set up one instance of JdbcTemplate when utilising Spring Data JDBC.

Java
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

@Configuration
public class JdbcTemplateConfig {

    // Configuring JdbcTemplate for the "todos" data source
    @Bean
    public JdbcTemplate todosJdbcTemplate(@Qualifier("todosDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    // Configuring JdbcTemplate for the "topics" data source
    @Bean
    public JdbcTemplate topicsJdbcTemplate(@Qualifier("topicsDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

Step 6: Confirm the EntityManager Factories

Therefore, we must specify factories for EntityManager for every data source.

Java
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.Objects;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackageClasses = Todo.class,
        entityManagerFactoryRef = "todosEntityManagerFactory",
        transactionManagerRef = "todosTransactionManager"
)
@EntityScan(basePackageClasses = Todo.class)
public class TodoJpaConfiguration {

    // Configuring the EntityManagerFactory for the "todos" data source
    @Bean
    public LocalContainerEntityManagerFactoryBean todosEntityManagerFactory(
            @Qualifier("todosDataSource") DataSource dataSource,
            EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(dataSource)
                .packages(Todo.class)
                .build();
    }

    // Configuring the TransactionManager for the "todos" data source
    @Bean
    public PlatformTransactionManager todosTransactionManager(
            @Qualifier("todosEntityManagerFactory") LocalContainerEntityManagerFactoryBean todosEntityManagerFactory) {
        return new JpaTransactionManager(Objects.requireNonNull(todosEntityManagerFactory.getObject()));
    }
}

Step 7: Add @ConfigurationProperties

All we have to do to set up Hikari is including a @ConfigurationProperties in the data source definition.

Java
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 javax.sql.DataSource;

@Configuration
public class TodosDataSourceConfig {

    // Configuring the Todos DataSource using Spring Boot's @ConfigurationProperties
    @Bean
    @ConfigurationProperties("spring.datasource.todos.hikari")
    public DataSource todosDataSource() {
        // Building and initializing the DataSource using properties
        return todosDataSourceProperties()
                .initializeDataSourceBuilder()
                .build();
    }

    // Additional method to configure DataSource properties
    @Bean
    @ConfigurationProperties("spring.datasource.todos.hikari")
    public DataSourceProperties todosDataSourceProperties() {
        return new DataSourceProperties();
    }
}

Conclusion

So, this is Configure Multiple DataSources in Spring Boot. In order to Create a Spring Boot Application that can interact with several databases, we must specify which configurations spring boot should use to determine when to run each source.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads