Cómo Configurar una Base de Datos IBM Db2 en un Contenedor Docker y Conectarla a su Aplicación Spring Boot con JDBC
Introducción
En el mundo del desarrollo de software, la elección de una base de datos adecuada es crucial para el éxito de cualquier aplicación. IBM Db2 es una opción popular que ofrece un sistema de base de datos relacional nativo en la nube, capaz de manejar grandes volúmenes de datos y soportar datos semiestructurados como JSON y XML. En este artículo, aprenderemos a establecer una base de datos Db2 utilizando un contenedor Docker y a conectarnos a ella desde una aplicación Spring Boot utilizando el controlador JDBC.
1. Overview
IBM Db2 es un sistema de base de datos relacional nativo en la nube que también soporta datos semiestructurados como JSON y XML. Está diseñado para manejar grandes volúmenes de datos con baja latencia. En este tutorial, configuraremos la edición comunitaria de un servidor de base de datos Db2 dentro de un contenedor Docker utilizando un archivo docker-compose.yml
. Luego, nos conectaremos a ella utilizando su controlador JDBC en una aplicación Spring Boot.
2. Db2 Database
El sistema de base de datos Db2 es conocido por manejar eficientemente grandes volúmenes de datos con un alto rendimiento. Es capaz de manejar datos estructurados y semiestructurados, lo que la hace versátil para diferentes modelos de datos. Además, está diseñada para aplicaciones tanto de microservicio como monolíticas.
Es importante mencionar que, aunque para acceder a todas sus capacidades se requiere una suscripción, existe una edición comunitaria gratuita disponible, la cual está limitada a un máximo de 16 GiB de almacenamiento y cuatro núcleos de CPU. Esta versión puede ser ideal para fines de prueba o aplicaciones de pequeña escala con necesidades limitadas de recursos.
3. Setup
Para empezar, configuraremos las dependencias para una aplicación Spring Boot y un servidor de base de datos Db2 dentro de un contenedor Docker.
3.1. Maven Dependencies
Primero, vamos a bootstrapping nuestra aplicación Spring Boot añadiendo las dependencias spring-boot-starter-web
y spring-boot-starter-data-jpa
a nuestro archivo pom.xml
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>3.4.3</version>
</dependency>
La dependencia spring-boot-starter-web
nos permite crear una aplicación web, incluyendo APIs RESTful y aplicaciones MVC. Por otro lado, spring-boot-starter-data-jpa
proporciona una herramienta de Mapeo Objeto-Relacional (ORM), simplificando la interacción con la base de datos al abstraer las consultas nativas, excepto cuando se definen explícitamente.
También añadimos la dependencia para el controlador JDBC de Db2 en nuestro pom.xml
:
<dependency>
<groupId>com.ibm.db2</groupId>
<artifactId>jcc</artifactId>
<version>12.1.0.0</version>
</dependency>
Esta dependencia com.ibm.db2
permite establecer una conexión con el servidor de base de datos Db2.
3.2. Db2 Docker Compose File
A continuación, definiremos un archivo docker-compose.yml
en nuestro directorio raíz del proyecto para ejecutar el servidor de la base de datos dentro de un contenedor Docker:
services:
db2:
image: icr.io/db2_community/db2
container_name: db2server
hostname: db2server
privileged: true
restart: unless-stopped
ports:
- "50000:50000"
environment:
LICENSE: accept
DB2INST1_PASSWORD: mypassword
DBNAME: testdb
BLU: "false"
ENABLE_ORACLE_COMPATIBILITY: "false"
UPDATEAVAIL: "NO"
TO_CREATE_SAMPLEDB: "false"
volumes:
- db2_data:/database
healthcheck:
test: ["CMD", "su", "-", "db2inst1", "-c", "db2 connect to testdb || exit 1"]
interval: 30s
retries: 5
start_period: 60s
timeout: 10s
volumes:
db2_data:
driver: local
La configuración anterior utiliza la imagen comunitaria más reciente de Db2, crea un usuario, establece una contraseña y inicializa una base de datos. En este caso, el nombre de usuario es db2inst1
, la contraseña es mypassword
, y el nombre de la base de datos es testdb
. Ahora, ejecutamos el comando docker compose up
para iniciar el servidor de base de datos.
4. Definición de Credenciales de Conexión en application.properties
Ahora que nuestro servidor de base de datos está en funcionamiento, definiremos los detalles de conexión en el archivo application.properties
:
spring.datasource.url=jdbc:db2://localhost:50000/testdb
spring.datasource.username=db2inst1
spring.datasource.password=mypassword
spring.datasource.driver-class-name=com.ibm.db2.jcc.DB2Driver
spring.jpa.database-platform=org.hibernate.dialect.DB2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
Aquí, definimos la URL de la base de datos que incluye el host, el puerto y el nombre de la base de datos a la que nos estamos conectando. Además, la URL comienza con jdbc:db2
, que es un subtipo de JDBC que indica que la conexión es a una base de datos Db2. A continuación, especificamos el nombre de usuario y la contraseña configurados en el archivo docker-compose.yml
. Es importante configurar la propiedad spring.datasource.driver-class-name
para asegurarnos de que Spring Boot cargue el controlador JDBC correcto de Db2.
5. Prueba de la Conexión
Ahora confirmaremos la conexión a la base de datos persistiendo un registro en testdb
.
5.1. Clase de Entidad
Primero, crearemos una clase de entidad llamada Article
:
<Entity>
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String body;
private String author;
// constructor estándar, getters y setters
}
La clase de entidad está mapeada a la tabla de la base de datos y sus columnas. A continuación, definimos un repositorio para manejar las operaciones de la base de datos:
public interface ArticleRepository extends JpaRepository<Article, Long> {
}
Ahora podemos persistir una entidad en la base de datos inyectando el repositorio en nuestro controlador.
5.2. Clase de Controlador
A continuación, crearemos una clase de controlador:
<RestController>
public class ArticleController {
private final ArticleRepository articleRepository;
public ArticleController(ArticleRepository articleRepository) {
this.articleRepository = articleRepository;
}
}
En el código anterior, utilizamos una inyección de dependencias basada en el constructor para inyectar el repositorio en la clase del controlador. Esto nos permite realizar varias operaciones en la base de datos, como guardar y recuperar artículos. Implementemos un endpoint POST para insertar un registro:
@PostMapping("/create-article")
public ResponseEntity<Article> createArticle(@RequestBody Article article, UriComponentsBuilder ucb) {
Article newArticle = new Article();
newArticle.setAuthor(article.getAuthor());
newArticle.setBody(article.getBody());
newArticle.setTitle(article.getTitle());
Article savedArticle = articleRepository.save(newArticle);
URI location = ucb.path("/articles/{id}").buildAndExpand(savedArticle.getId()).toUri();
return ResponseEntity.created(location).body(savedArticle);
}
En el código anterior, creamos un endpoint que acepta un objeto Article
como cuerpo de la solicitud y lo guarda en la base de datos. Además, devolvemos un estado HTTP 201 (Creado).
5.3. Prueba de Integración
Finalmente, escribiremos una prueba de integración usando la clase RestTemplate
para verificar el comportamiento de la solicitud POST. Primero, crearemos una clase de prueba de integración:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ArticleApplicationIntegrationTest {
}
Luego, inyectaremos la instancia de RestTemplate
:
@Autowired
TestRestTemplate restTemplate;
A continuación, escribimos un método de prueba para enviar una solicitud POST y verificar la respuesta:
@Test
void givenNewArticleObject_whenMakingAPostRequest_thenReturnCreated() {
Article article = new Article();
article.setTitle("Introduction to Java");
article.setAuthor("Baeldung");
article.setBody("Java is a programming language created by James Gosling");
ResponseEntity<Article> createResponse
= restTemplate.postForEntity("/create-article", article, Article.class);
assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.CREATED);
URI locationOfNewArticle = createResponse.getHeaders().getLocation();
ResponseEntity<String> getResponse
= restTemplate.getForEntity(locationOfNewArticle, String.class);
assertThat(getResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
}
En el código anterior, afirmamos que el registro se crea con éxito y que obtenerlo por id
devuelve una respuesta HTTP 200.
6. Conclusión
En este artículo, aprendimos cómo configurar una base de datos IBM Db2 y conectarnos a ella utilizando el controlador Db2, configurado en el archivo application.properties
de una aplicación Spring Boot. Además, hemos probado la conexión al persistir un registro en la base de datos.
Los programadores que desean implementar IBM Db2 en sus aplicaciones pueden beneficiarse de la edición comunitaria para fines de prueba y desarrollo. Es crucial seguir las mejores prácticas de conexión y asegurarse de manejar adecuadamente las excepciones y errores en la implementación.
Conocer el flujo entre usado en la aplicación y la base de datos puede ofrecer muchos beneficios, especialmente cuando enfrentamos problemas de rendimiento o escalabilidad. Aprender a establecer y gestionar conexiones sigue siendo una habilidad clave en el campo de la programación basada en datos.
Ahora, es momento de implementar esta configuración en sus propios proyectos y explorar las capacidades de IBM Db2. ¡Feliz codificación!