• Home
  • Introduccion
  • Configuración de Múltiples Fuentes de Datos en una Aplicación Spring Boot
3.0 / 5

Configuración de Múltiples Fuentes de Datos en una Aplicación Spring Boot

0
3

En las aplicaciones a nivel empresarial, es común tener múltiples bases de datos. Esto puede deberse a varias razones, como separar las operaciones de lectura y escritura, manejar sistemas heredados, entre otras. Con algunos ajustes de configuración, Spring Boot simplifica el proceso de configurar múltiples fuentes de datos en la aplicación. En este tutorial, vamos a profundizar en esta configuración de múltiples fuentes de datos.

Escenario

Una aplicación Spring Boot necesita leer datos de una base de datos MySQL de solo lectura, procesar los datos y escribirlos en una PostgresDB. Aquí configuraremos estas dos fuentes de datos en nuestra aplicación Spring Boot.

Requisitos Previos

Antes de entrar en el proceso, asegurémonos de cumplir con los siguientes requisitos previos:

  • Un proyecto Spring Boot configurado en el IDE (para esta demostración estoy usando Spring Initializr).
  • Dos fuentes de datos (PostgreSQL y MySQL).

Paso 1: Configuración de Dependencias

Para este tutorial, vamos a usar JPA para interactuar con las fuentes de datos. Así que añade Spring Data JPA starter como una dependencia. Además, necesitamos las dependencias de Postgres y MySQL para las fuentes de datos.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>{última versión aquí}</version>
</dependency>
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>{última versión aquí}</version>
</dependency>
Code language: YAML (yaml)

Paso 2: Definir Propiedades de Configuración de las Fuentes de Datos

En una configuración de fuente de datos única, añadimos la siguiente configuración al archivo application.properties:

# DataSource
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=usuario
spring.datasource.password=contraseña
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
Code language: YAML (yaml)

Durante el inicio, la auto-configuración de Spring crea una instancia de org.springframework.boot.autoconfigure.jdbc.DataSourceProperties y asigna estas configuraciones a los campos de DataSourceProperties.

La anotación @ConfigurationProperties en Spring Boot se usa para vincular propiedades externas (generalmente definidas en archivos application.properties o application.yml) a un objeto Java.

Para configurar múltiples fuentes de datos, necesitamos definir ambas configuraciones en el archivo application.properties de la siguiente manera:

# Primera Fuente de Datos
spring.datasource.first.url=jdbc:mysql://localhost:3306/readingdb
spring.datasource.first.username=usuario
spring.datasource.first.password=contraseña
spring.datasource.first.driverClassName=com.mysql.cj.jdbc.Driver

# Segunda Fuente de Datos
spring.datasource.second.url=jdbc:postgresql://localhost:5432/writingdb
spring.datasource.second.username=usuario
spring.datasource.second.password=contraseña
spring.datasource.second.driverClassName=org.postgresql.Driver
Code language: YAML (yaml)

Para vincular las propiedades externas de ambas fuentes de datos, necesitamos usar @ConfigurationProperties.

@Configuration
public class WritingDatasourceConfiguration {
    @Bean
    @ConfigurationProperties("spring.datasource.second")
    public DataSourceProperties writingDataSourceProperties() {
        return new DataSourceProperties();
    }
}

@Configuration
public class ReadingDatasourceConfiguration {
    @Bean
    @ConfigurationProperties("spring.datasource.first")
    public DataSourceProperties readingDataSourceProperties() {
        return new DataSourceProperties();
    }
}
Code language: Java (java)

Paso 3: Crear Fuentes de Datos Usando las Configuraciones

En el paso 2, hemos mapeado con éxito las propiedades de ambas fuentes de datos a DataSourceProperties. Ahora, vamos a crear las fuentes de datos utilizando estas propiedades.

@Configuration
public class WritingDatasourceConfiguration {
    @Bean
    @ConfigurationProperties("spring.datasource.second")
    public DataSourceProperties writingDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    public DataSource writingDataSource() {
        return writingDataSourceProperties()
          .initializeDataSourceBuilder()
          .build();
    }
}
Code language: Java (java)

De manera similar, crea configuraciones para la segunda fuente de datos:

@Configuration
public class ReadingDatasourceConfiguration {
    @Bean
    @ConfigurationProperties("spring.datasource.first")
    public DataSourceProperties readingDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    public DataSource readingDataSource() {
        return readingDataSourceProperties()
          .initializeDataSourceBuilder()
          .build();
    }
}
Code language: Java (java)

La necesidad de la anotación @Primary en el bean readingDatasource se explicará en la siguiente sección.

Paso 4: Configuración de Spring Data JPA

Para usar Spring Data JPA, necesitamos declarar las fábricas de EntityManager para ambas fuentes de datos. Esta declaración especificará:

  • Qué paquete buscar para las entidades.
  • Qué paquete tiene las clases de repositorio.

Por ejemplo, observa la configuración ReadingDataSourceJPAConfig:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = "com.example.readingdb.repository",
        entityManagerFactoryRef = "readingEntityManagerFactory",
        transactionManagerRef = "readingTransactionManager"
)
public class ReadingDataSourceJPAConfig {
    @Bean
    public LocalContainerEntityManagerFactoryBean readingEntityManagerFactory(
      @Qualifier("readingDataSource") DataSource dataSource,
      EntityManagerFactoryBuilder builder) {
        return builder
          .dataSource(dataSource)
          .packages("com.example.readingdb.model")
          .build();
    }

    @Bean
    public PlatformTransactionManager readingTransactionManager(
      @Qualifier("readingEntityManagerFactory") LocalContainerEntityManagerFactoryBean readingEntityManagerFactory) {
        return new JpaTransactionManager(Objects.requireNonNull(readingEntityManagerFactory.getObject()));
    }
}
Code language: Java (java)

El EntityManagerFactoryBuilder en el bean readingEntityManagerFactory espera solo una fuente de datos durante la inyección de la fuente de datos (org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration). Por lo tanto, necesitamos especificar una de las fuentes de datos como primaria usando la anotación @Primary. De ahí que el readingDataSource en el paso anterior fue hecho primario.

De manera similar, crea una configuración JPA para la segunda fuente de datos:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = "com.example.writingdb.repository",
        entityManagerFactoryRef = "writingEntityManagerFactory",
        transactionManagerRef = "writingTransactionManager"
)
public class WritingDataSourceJPAConfig {
    @Bean
    public LocalContainerEntityManagerFactoryBean writingEntityManagerFactory(
      @Qualifier("writingDataSource") DataSource dataSource,
      EntityManagerFactoryBuilder builder) {
        return builder
          .dataSource(dataSource)
          .packages("com.example.writingdb.model")
          .build();
    }

    @Bean
    public PlatformTransactionManager writingTransactionManager(
      @Qualifier("writingEntityManagerFactory") LocalContainerEntityManagerFactoryBean writingEntityManagerFactory) {
        return new JpaTransactionManager(Objects.requireNonNull(writingEntityManagerFactory.getObject()));
    }
}
Code language: Java (java)

¡Eso es todo, amigos! Hemos configurado con éxito una aplicación Spring Boot con múltiples fuentes de datos. Al iniciar, deberíamos ver la configuración de ambas fuentes de datos en los registros como este:

com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
com.zaxxer.hikari.pool.HikariPool  : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@1da4b3f9
com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.

com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Starting...
com.zaxxer.hikari.pool.HikariPool  : HikariPool-2 - Added connection org.postgresql.jdbc.PgConnection@28daf506
com.zaxxer.hikari.HikariDataSource : HikariPool-2 - Start completed.
Code language: YAML (yaml)

Podemos proceder con la configuración de la entidad y el repositorio desde aquí.

Puedes encontrar el código para esta demostración aquí: Repositorio de GitHub. He añadido un docker-compose con dos bases de datos para una fácil ejecución.

Mantente feliz, sigue codificando.

Fuente aquí.

THIS IS AN OPTIONAL

Related Post

LEAVE YOUR COMMENTS