How to Configure Multiple Data Sources in Spring Boot with JdbcTemplate, JPA, and MyBatis

This tutorial walks through adding and initializing multiple Spring Boot data sources for JdbcTemplate, Spring Data JPA, and MyBatis, including property setup, configuration classes, bean definitions, testing code, and repository links for complete examples.

Programmer DD
Programmer DD
Programmer DD
How to Configure Multiple Data Sources in Spring Boot with JdbcTemplate, JPA, and MyBatis

In previous tutorials we introduced three common data access methods: JdbcTemplate, Spring Data JPA, and MyBatis.

JdbcTemplate

Spring Data JPA

MyBatis

Now we will explain, in three parts, how to configure multiple data sources for each method.

Adding Multi‑Data‑Source Configuration

First, add two data source definitions in application.properties:

spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver

Notes:

When configuring multiple data sources, the prefix spring.datasource is followed by a name such as primary or secondary to distinguish each source.

Configuration keys differ between Spring Boot 2.x ( spring.datasource.secondary.jdbc-url) and 1.x ( spring.datasource.secondary.url).

If you encounter

java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.

, the issue lies in the configuration.

Initializing Data Sources and JdbcTemplate

Create a configuration class to load the properties, instantiate the data sources, and define a JdbcTemplate for each:

@Configuration
public class DataSourceConfiguration {

    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource primaryDataSource) {
        return new JdbcTemplate(primaryDataSource);
    }

    @Bean
    public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
        return new JdbcTemplate(secondaryDataSource);
    }
}

Notes:

The first two beans create the data sources using @ConfigurationProperties to bind spring.datasource.primary.* and spring.datasource.secondary.*.

The @Primary annotation marks the primary data source, which is used when no specific source is requested.

The last two beans create a JdbcTemplate for each data source, injecting the corresponding DataSource bean.

Testing the Configuration

Write a test class to verify that the two data sources operate independently:

@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter37ApplicationTests {

    @Autowired
    protected JdbcTemplate primaryJdbcTemplate;

    @Autowired
    protected JdbcTemplate secondaryJdbcTemplate;

    @Before
    public void setUp() {
        primaryJdbcTemplate.update("DELETE FROM USER");
        secondaryJdbcTemplate.update("DELETE FROM USER");
    }

    @Test
    public void test() throws Exception {
        // Insert two rows into the primary data source
        primaryJdbcTemplate.update("insert into user(name,age) values(?, ?)", "aaa", 20);
        primaryJdbcTemplate.update("insert into user(name,age) values(?, ?)", "bbb", 30);

        // Insert one row into the secondary data source
        secondaryJdbcTemplate.update("insert into user(name,age) values(?, ?)", "ccc", 20);

        // Verify counts
        Assert.assertEquals("2", primaryJdbcTemplate.queryForObject("select count(1) from user", String.class));
        Assert.assertEquals("1", secondaryJdbcTemplate.queryForObject("select count(1) from user", String.class));
    }
}

Notes:

When two JdbcTemplate beans exist, Spring resolves them by bean name if no @Qualifier is used.

Bean names default to the method names, so the injection matches the defined beans.

Code Repository

The complete examples are available in the chapter3-7 directory of the following repositories:

GitHub: https://github.com/dyc87112/SpringBoot-Learning/

Gitee: https://gitee.com/didispace/SpringBoot-Learning/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Spring BootMyBatisJdbcTemplatespring-data-jpaMulti Data Source
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.