• Giovanny Rey Cediel

Configuración de Bases de Datos Relacionales

En Pasos para Crear un Microservicio con Spring Boot en Eclipse vimos como crear un microservicio, sin embargo allí, explícitamente le indicamos a Spring Boot que excluyera la configuración para acceder a fuentes de datos. En esta oportunidad vamos a tratar dicha configuración para acceder a las bases de datos Postgres y MySQL.


En Spring Boot la configuración de bases de datos, se realiza de diferentes formas. Aquí hablaremos de dos. Una manera es usando las propiedades spring.datasource.*, que por ser establecidas en el archivo application.properties, permiten la creación automática del objeto javax.sql.DataSource, el cual representa la conexión hacia la base de datos. La otra manera es cambiando el namespace spring por un namespace personalizado, como por ejemplo ds.postgres. En este caso será necesario definir una clase de configuración, que referencie dichas propiedades para ser enlazadas en el objeto javax.sql.DataSource. Como veremos más adelante, esta última configuración nos resulta útil para acceder a multiples bases de datos.


Configuración de Postgres con propiedades spring.datasource.*

Código fuente: https://github.com/giovynet/auto_conf_postgres.git


Cuando desarrollamos una aplicación en Spring Boot para acceder a una única base de datos, la configuración es muy trivial. Es solo cuestión de definir algunas propiedades en el archivo application.properties.


Primero que todo debemos asegurar que nuestro microservicio incluye las dependencias Spring Data JDBC y Postgres SQL Driver. Esto lo podemos hacer siguiendo los pasos descritos en el artículo: Adicionar o Suprimir Dependencias en Proyecto Spring Boot.


Ahora que tenemos las dependencias en el proyecto, debemos asegurar que en el archivo application.properties no se excluya la auto-configuración de fuentes de datos. En caso de existir la siguiente linea debemos comentarla o suprimirla.

Luego vamos a establecer la URL de conexión hacia la base de datos, el nombre de usuario (username) y contraseña (password). La URL aquí, es la manera de identificar una base de datos para que un controlador adecuado la reconozca y se conecte a ella. La siguiente linea describe una URL de conexión hacia un servidor de base de datos Postgres que responde por el puerto 5432 y se conecta a la base de datos my_db.

spring.datasource.url=jdbc:postgresql://localhost:5432/my_db

La palabra localhost indica que el servidor de base de datos se encuentra en el mismo host donde se ejecuta la aplicación —el microservicio que se conectará a la base de datos. En caso que la base de datos y la aplicación se encuentren alojados en servidores diferentes, la palabra localhost se se debe reemplazar por la IP o el dominio del servidor de base de datos.


Las credenciales que permiten el acceso a la base de datos se establecen de la siguiente manera:

spring.datasource.username=appPostgres
spring.datasource.password=123PostgresKey

El nombre de usuario en este caso es appPostgres y la contraseña es 123PostgresKey. La cantidad de conexiones disponibles, el manejo transaccional y los tiempos de espera, son parámetros que maneja Spring Boot con ayuda del gestor de conexiones HikariCP, del cual hablamos en el artículo Gestión de Pool de Conexiones con HikariCP. A modo de ejemplo asumiremos la necesidad de un pool con un tamaño máximo de 10 conexiones. También vamos a establecer un tiempo de 20 segundos que un cliente debe esperar por una conexión disponible, antes de lanzar una excepción por time-out. Las siguientes dos lineas expresan el citado ejemplo:

spring.datasource.hikari.maximum-pool-size = 10
spring.datasource.hikari.connection-timeout = 20000

Finalmente, el archivo debería lucir como se muestra a continuación :

La configuración de arriba es suficiente para acceder a Postgres, de hecho, para realizar una consulta, bastaría con inyectar un objeto de tipo jdbcTemplate en una clase decorada con @Repositoy, y usar el método query, tal como se observa a continuación:

El anterior código lo podemos probar con la siguiente clase unitaria:

La ejecución de la clase anterior debería imprimir una lista de ciudades, evidenciando la conexión y el acceso correcto hacia la base de datos.

Spring Data JDBC presenta una serie de métodos para realizar operaciones hacia la base de datos, de los cuales hablaremos en otros artículos. Por ahora, nos centraremos únicamente en la configuración para acceder a las bases de datos.


Configuración de MySQL con propiedades spring.datasource.*

Código fuente: https://github.com/giovynet/auto_conf_mysql.git


Primero debemos incluir en el microservicio las dependencias Spring Data JDBC y MySQL Driver, siguiendo los pasos descritos en el artículo: Adicionar o Suprimir Dependencias en Proyecto Spring Boot.


La configuración de MySQL con parámetros spring.datasorce.* es similar a la de Postgres ya que utiliza los mismos parámetros que allí vimos. Solo cambiaremos los valores de la URL y las credenciales de acceso, de tal manera que el archivo application.properties debería lucir así:


Configuración de con Namespace Personalizado

Hasta aquí, hemos visto como configurar bases de datos como Postgres o MySQL con las propiedades spring.datasoure.*, vimos que de esta manera no tenemos que hacer nada más, ya que Spring Boot crea por nosotros el objeto dataSource de acuerdo a las propiedades establecidas. Ahora vamos a realizar esta misma tarea pero con propiedades personalizadas. Este tipo de configuración normalmente es usado para acceder a varias fuentes de datos, primero veremos la configuración para acceder a una fuente de datos Postgres. Finalmente veremos como acceder a dos fuentes de datos, Postgres y MySQL en el mismo microservicio.


Configuración de Postgres con namespace personalizado

Código fuente: https://github.com/giovynet/custom_namespace_postgres.git


Las propiedades spring.datasource.* son establecidas en el archivo application.properties para crear de forma automática un objeto de tipo javax.sql.DataSource, el cual es una fabrica de conexiones hacia una única fuente de datos. Para establecer conexión, este objeto usa una URL y credenciales de acceso. ¿Que pasaría si cambiáramos el namespace spring?, la respuesta es que Spring Boot no sería capaz de crear automáticamente el objeto javax.sql.DataSource. ¿En que casos necesitamos cambiar el namespace spring? una respuesta es, cuando necesitemos configurar más de una fuente de datos, para distinguir entre ellas.


Spring Boot nos permite cambiar el namespace, pero debemos tener en cuenta los siguientes cuatro aspectos:

  1. Un mismo namespace debe usarse para referenciar las propiedades de una única fuente de datos.

  2. La propiedad URL, debe cambiarse por jdbcUrl.

  3. Las propiedades asociadas a la gestión del pool de conexiones, no deberían presentar el sub-namespace “hikari”.

  4. Se debe crear una clase de configuración que fabrique el objeto javax.sql.DataSource de acuerdo a las propiedades con prefijo personalizado.

Los primeros tres aspectos se ilustran en el siguiente archivo de configuración:

En la anterior configuración observamos que el prefijo spring fue cambiado por ds.postgres, también se cambió la propiedad URL por jdbcUrl, y las propiedades asociadas a la gestión del pool de conexiones, no llevan el sub-namespace “hikari”. Esto no significa que HikariCP deje de funcionar. HikariCP es el gestor de conexiones por defecto de Spring Boot. Sin embargo, cuando cambiamos el prefijo spring, la auto-configuración en Spring Boot ya no requiere explicitamente el sub-namespace hikari.


El tercer aspecto lo vemos reflejado en la siguiente clase de configuración:


Como vimos en el artículo Inversión de Control en Spring Boot, los métodos decorados con @Bean retornan objetos administrados por el contenedor IoC, vemos que este decorador se encuentra sobre el método dataSourceOne(), el cuál retornará un objeto de tipo javax.sql.DataSource, también vemos que se le asignó el nombre ds-postgres, que más adelante nos servirá para referenciarlo desde otro lugar.


La sentencia DataSourceBuilder.create().build() construye el objeto javax.sql.DataSource. El decorador @ConfigurationProperties con el parámetro prefix = "ds.postgres.datasource”, indica el conjunto de propiedades que Spring Boot tendrá en cuenta para la configuración del objeto javax.sql.DataSource.


De esta manera ya tenemos configurado nuestro microservicio para acceder a Postgres. Si usamos las clases de repositorio y de prueba unitaria, que usamos en la sección Configuración de Postgres con propiedades spring.datasource.*, el resultado será el mismo. Incluso, realizando debug sobre el objeto dataSource podemos verificar las propiedades establecidas, como se muestra en la siguiente imagen:


Configuración de dos bases de datos con namespace personalizado

Código fuente: https://github.com/giovynet/custom_namespace_mysql_postgres.git


Tal como hicimos en las anteriores secciones, antes de comenzar, debemos agregar al microservicio las dependencias Spring Data JDBC, Postgres SQL Driver y MySQL Driver.


Configurar dos bases de datos implica los siguientes 3 pasos:

  1. Añadir dos conjuntos de propiedades, cada una con su propio namespace en el archivo application.properties.

  2. Una clase de configuración con dos métodos que construyen los dos objetos javax.sql.DataSource, uno que representa la conexión hacia Postgres y otro hacia MySQL.

  3. En la misma clase de configuración, se deben crear dos métodos que construyan los objetos jdbcTemplate, uno para cada base de datos.

El primer paso lo vemos reflejado en el siguiente archivo application.properties:

En la anterior configuración observamos dos conjuntos de propiedades, una con el namespace personalizado ds.postgres, otra con el namespace personalizado ds.mysql. Para cada una se define la URL que corresponda a la base de datos a la que hace referencia, las credenciales de acceso, el tamaño máximo de pool de conexiones y el tiempo máximo de espera por una conexión desde el pool.


Los pasos segundo y tercero, los vemos reflejados en la siguiente clase de configuración:

Del anterior código observamos los métodos dataSourcePostgres() y dataSourceMySQL(), los cuales retornan objetos javax.sql.DataSource, que representan las conexiones hacia las bases de datos Postgres y MySQL.

Observamos también, los métodos jdbcTemplatePostgres(DataSource ds) y jdbcTemplateMysql(DataSource ds), que retornan objetos JdbcTemplate para realizar operaciones SQL en cada una de las bases de datos. Llama la atención, que cada método recibe como parámetro el correspondiente javax.sql.DataSource. Para hacer esto, se usa la anotación @Qualifier con el identificador del método que construye el javax.sql.DataSource. Así, por ejemplo, @Qualifier("ds-postgres), referenciará el método dataSourcePostgres(), y @Qualifier("ds-mysql") referenciará el método dataSourceMySQL().


La configuración anterior es suficiente para realizar consultas en las dos bases de datos. Tan solo es necesario inyectar los objetos jdbcTemplate asociados con Postgres y MySQL, en una clase decorada con @Repository, y utilizar a conveniencia el método query, tal como se muestra a continuación:

De la clase anterior, observamos que el método selectColorsFromMysql() realiza una consulta hacia MySQL y retorna una lista de colores. El método selectCitiesFromPostgres() realiza una consulta hacia Postgres y retorna una lista de ciudades. Podemos probar estas consultas con la siguiente clase unitaria:

La ejecución de la clase anterior imprimirá dos listas, una con información de colores almacenada en MySQL, y otra con información de ciudades almacenada en Postgres, así como se muestra en la siguiente impresión de pantalla.

En este artículo hemos visto las propiedades típicas que debemos establecer en el archivo application.properties para que un microservicio pueda acceder a bases de datos como Postgres o MySQL. También vimos, como acceder a estas bases de datos al mismo tiempo, mediante la configuración de propiedades con namespaces personalizados y clases de configuración.


Copyright Giovynet.com 2018 - 2020