Configuring Multiple Data Sources in a Spring Boot Application
Configuring Multiple Data Sources in Spring Boot
To support heterogeneous database access—such as reading from both MySQL and PostgreSQL—Spring Boot applications can be configured with multiple data sources using dynamic routing.
Dependency Setup
Add the following dependencies to pom.xml:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.1</version>
</dependency>
DataSource Configuration
Define two named data sources in application.yml:
spring:
datasource:
dynamic:
primary: postgresql
strict: false
datasource:
postgresql:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/myapp_pg
username: pg_user
password: pg_pass
mysql:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/myapp_mysql?useSSL=false&serverTimezone=UTC
username: mysql_user
password: mysql_pass
The primary key specifies the default data source used when no explicit routing is declared.
Mapper Organization and Routing
Group mapper interfaces by target database. For example:
src/main/java/com/example/mapper/postgres/contains interfaces for PostgreSQL.src/main/java/com/example/mapper/mysql/contains interfaces for MySQL.
Corresponding XML maping files should follow the same structure under src/main/resources/mapper/.
Configure MyBatis Plus to scan mappers correctly:
mybatis-plus:
mapper-locations: classpath:mapper/**/*Mapper.xml
Data Source Selection at Runtime
Use the @DS annotation on mapper interfaces or methods to route queries:
@Mapper
@DS("postgresql")
public interface UserPostgreSqlMapper {
List<User> findAll();
}
@Mapper
@DS("mysql")
public interface OrderMySqlMapper {
List<Order> findRecent();
}
Omitting @DS defaults to the primary data source (postgresql, per configuration). Explicit annotation improves clarity and maintainability.
Optional: Custom DataSource Resolver
For programmatic control, inject DynamicRoutingDataSource and use DsContextHolder.set("mysql") before operations—though declarative @DS is preferred for most cases.