Spring Boot
Database Configuration
Multiple Datasources
Application Properties
Java Spring

How can I provide different database configurations with Spring Boot?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

In Spring Boot, “different database configurations” can mean two different problems. Sometimes you want one datasource that changes by environment, such as dev, test, and prod. Other times you want multiple datasources active in the same application.

Those are different designs and should not be mixed casually. The most common and simplest solution is environment-specific configuration using profiles.

Use Profiles for Different Environments

If the application uses one database at a time but the connection details differ by environment, use Spring profiles with separate property files.

Base configuration:

yaml
1# application.yml
2spring:
3  datasource:
4    driver-class-name: org.postgresql.Driver
5  jpa:
6    hibernate:
7      ddl-auto: validate

Development settings:

yaml
1# application-dev.yml
2spring:
3  datasource:
4    url: jdbc:postgresql://localhost:5432/app_dev
5    username: app_dev
6    password: dev-secret

Production settings:

yaml
1# application-prod.yml
2spring:
3  datasource:
4    url: jdbc:postgresql://prod-db.internal:5432/app
5    username: app_prod
6    password: ${DB_PASSWORD}

Then activate the profile:

bash
java -jar app.jar --spring.profiles.active=dev

This is the standard Spring Boot answer when you need different connection values per environment.

Why Profiles Are Usually the Best First Choice

Profiles keep one application design with one datasource bean, while allowing environment-specific details to change cleanly. That is much easier to maintain than building custom datasource selection logic when all you really need is different URLs and credentials.

For tests, you can also have:

yaml
1# application-test.yml
2spring:
3  datasource:
4    url: jdbc:h2:mem:testdb
5    username: sa
6    password:

That gives you lightweight test isolation without affecting dev or prod.

Environment Variables and External Config

Profiles are useful, but hardcoding secrets is not. In practice, many teams combine profiles with environment variables or externalized config values.

For example:

yaml
1spring:
2  datasource:
3    url: ${DB_URL}
4    username: ${DB_USERNAME}
5    password: ${DB_PASSWORD}

Now the profile can still control other behavior, while deployment-specific credentials come from the environment.

This is usually a better production strategy than committing passwords into profile files.

When You Actually Need Multiple Datasources

If the application must connect to two databases at the same time, profiles are not enough. You need multiple datasource beans.

Example:

java
1@Configuration
2public class DataSourceConfig {
3
4    @Bean
5    @ConfigurationProperties("app.datasource.primary")
6    public DataSource primaryDataSource() {
7        return DataSourceBuilder.create().build();
8    }
9
10    @Bean
11    @ConfigurationProperties("app.datasource.reporting")
12    public DataSource reportingDataSource() {
13        return DataSourceBuilder.create().build();
14    }
15}

And configuration:

yaml
1app:
2  datasource:
3    primary:
4      url: jdbc:postgresql://localhost:5432/app
5      username: app
6      password: secret
7    reporting:
8      url: jdbc:mysql://localhost:3306/reporting
9      username: reports
10      password: reports-secret

This is a different design from environment switching. Do not introduce multiple datasources unless the application truly needs them simultaneously.

Use Profiles With Multiple Datasources Carefully

You can combine both ideas. For example, the app may always have a primary and reporting datasource, but each one needs different values in dev and prod.

That works, but it increases complexity quickly, so it is worth keeping the property structure clear and predictable.

The general rule is:

  • use profiles for environment differences
  • use multiple datasource beans only for true multi-database application architecture

A Practical Recommendation

For most projects:

  1. start with application.yml
  2. move environment-specific values into application-dev.yml, application-test.yml, and application-prod.yml
  3. keep passwords and sensitive values in environment variables or secret stores
  4. only add multiple datasource beans if the application genuinely needs more than one live connection target

That avoids unnecessary complexity while staying aligned with normal Spring Boot conventions.

Common Pitfalls

One common mistake is creating custom Java config for environment switching when Spring profiles already solve the problem.

Another mistake is copying entire datasource blocks across profile files without understanding which values actually differ. That creates drift and makes updates harder.

It is also easy to confuse “different database configurations” with “multiple datasources.” Those are not the same requirement.

Finally, do not store production credentials directly in committed config files. Externalize secrets even if the rest of the configuration lives in YAML.

Summary

  • Use Spring profiles when the app needs one datasource with different settings per environment.
  • Use separate property files such as application-dev.yml and application-prod.yml.
  • Externalize sensitive values with environment variables or secret management.
  • Use multiple datasource beans only when the app truly connects to more than one database at the same time.
  • Keep the design simple unless the architecture genuinely requires extra configuration layers.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.