Aplicación Spring Boot con MySQL y Docker

 1,398 total views,  10 views today

Introducción

En este artículo vamos  a crear una aplicación con Spring Boot, MySQL, JPA y además utilizando contenedores.

A continuación, para este ejemplo utilizaremos Docker para crear y ejecutar la imagen de la aplicación como un contenedor Docker.

Por lo tanto diseñaremos una solución de gestión de usuarios, para realizar ingresos y consultas en la base de datos.

Requisitos

Lenguaje de programación Java SE 11 Oracle:

https://www.oracle.com/java/technologies/javase-jdk11-downloads.html
Version Recomendad: AdoptOpenJDK

https://adoptopenjdk.net/installation.html

Entorno Integrado de Desarrollo (IDE) Intellij https://www.jetbrains.com/idea/download/
Base de Datos MySQL
Docker Docker https://www.docker.com/get-started
Postman Postman  https://www.postman.com/

 

Creación de la aplicación en Spring Boot

Ingresamos al sitio web https://start.spring.io/ para esta demo. Creamos un proyecto con Maven, en lenguaje seleccionamos Java. Continuamos para seleccionar la versión de Spring boot, para esta demo escogemos la version estable 2.2.6. En el paso siguiente diligenciamos los datos del proyecto, donde definiremos nuestro ID de grupo que también se convertirá en un paquete base en nuestro proyecto Java. En el campo Artefacto, definiremos el ID del artefacto, que también será el nombre de nuestro proyecto.

Por último seleccionamos las Dependencias que se utilizaran en la demo, para este ejemplo seleccionamos las siguientes dependencias Spring Data JPA,  Spring Web Starter y MySQL Driver. Una de las ventajas de Spring Boot es que proporciona paquetes iniciales que simplifica su configuración de Maven. Los iniciadores Spring Boot son en realidad un conjunto de dependencias que puede incluir en su proyecto. Puede escribir las dependencias en el campo de búsqueda o cambiar a la versión completa y ver todos los paquetes de inicio y las dependencias disponibles como se puede observar en la figura 1.

Boot de Spring Boot
Inicializador de Spring Boot

Figura 1

Estructura de la Aplicación

Como se puede observar la figura 2, la estructura de la aplicación estará divida por paquete.

Figura 2

El archivo pom.xml contiene toda la información básica sobre el proyecto, como pueden observar en este archivo, podemos adicionar las dependencias, configurar los datos, los plugins y las propiedades del proyecto.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.5.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example.jugnicaragua</groupId>
	<artifactId>jugnicaragua</artifactId>
	<version>1.0.0</version>
	<name>jugnicaragua</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>11</maven.compiler.source>
		<maven.compiler.target>11</maven.compiler.target>
		<java.version>11</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
	</dependencies>
	<build>
	   <plugins>
	       <plugin>
	          <groupId>org.springframework.boot</groupId>
	          <artifactId>spring-boot-maven-plugin</artifactId>
	           <configuration>
		       <finalName>demo-nica</finalName>
		   </configuration>
	        </plugin>
		<plugin>
		    <groupId>org.apache.maven.plugins</groupId>
		    <artifactId>maven-compiler-plugin</artifactId>
		    <version>3.8.0</version>
		       <configuration>
			  <source>${java.version}</source>
			  <target>${java.version}</target>
		       </configuration>
		</plugin>
	     </plugins>
          </build>
</project>

Una breve explicación de las clases o interfaces que se utilizarán en el ejemplo.

Person.java

Esta clase de modelo representa una persona. Contiene un id de persona que se  auto-genera, con sus respectivo nombre y apellido, como se puede observar la figura 3.

package com.example.jugnicaragua.jugnicaragua.model;

import javax.persistence.*;

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="idperson")
    private Long idPerson;

    @Column(name="firstname", nullable = false, length=70)
    private String firstName;

    @Column(name="lastname", nullable = false, length=70)
    private String lastName;

    public Long getIdPerson() {
        return idPerson;
    }

    public void setIdPerson(Long idPerson) {
        this.idPerson = idPerson;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

Figura 3

IPersonDAO.java

El Spring Boot Data JPA proporciona una interfaz CrudRepository para dar soporte a las operaciones básicas de las operaciones CRUD, dándole funcionalidades a la clase entidad, como se puede observar la figura 4.

package com.example.jugnicaragua.jugnicaragua.dao;

import com.example.jugnicaragua.jugnicaragua.model.Person;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface IPersonDAO extends CrudRepository<Person, Long> {

}

Figura 4

PersonaService.java

La clase de PersonaService facilita la comunicación del repositorio con las operaciones de guardar, actualizar, eliminar, listar por IdPersona y listar todas las personas, como se puede observar la figura 5.

package com.example.jugnicaragua.jugnicaragua.service;

import com.example.jugnicaragua.jugnicaragua.dao.IPersonDAO;
import com.example.jugnicaragua.jugnicaragua.model.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class PersonService {

    @Autowired
    private IPersonDAO dao;

    public Person save(Person t) { return dao.save(t); }

    public Person update(Person t) { return dao.save(t); }

    public void delete(Person t) { dao.delete(t); }

    public Iterable<Person> list() { return dao.findAll(); }

    public Optional<Person> listId(long id) {
        return dao.findById(id);
    }

}

Figura 5

PersonController.java

Los servicios web son aplicaciones que se comunican a través de Internet utilizando el protocolo HTTP. Hay muchos tipos diferentes de arquitecturas de servicios web, pero la idea principal en todos los diseños es la misma. En este artículo estamos creando un servicio web RESTful a partir de lo que es un diseño, con el objetivo de ver la información de una persona. crear endpoint permite crear un nuevo registro de la persona en el sistema. También existe la opción de un endpoint, donde devuelve una respuesta JSON donde se visualiza la información de todas las personas disponibles en la aplicación, ver/{id} endpoint permite buscar información de la persona con el id de persona apropiada, como se puede observar la figura 6.

package com.example.jugnicaragua.jugnicaragua.controller;

import com.example.jugnicaragua.jugnicaragua.exception.ModelNotFoundException;
import com.example.jugnicaragua.jugnicaragua.model.Person;
import com.example.jugnicaragua.jugnicaragua.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;

@RestController
public class PersonController {

    @Autowired
    PersonService personService;

    @PostMapping("/save")
    public long save(@RequestBody Person person) {
        personService.save(person);
        return person.getIdPerson();
    }

    @GetMapping("/listAll")
    public Iterable<Person> listAllPersons() {
        return personService.list();
    }

    @GetMapping("/list/{id}")
    public Person listPersonById(@PathVariable("id") int id) {
        Optional<Person> person = personService.listId(id);
        if(person.isPresent()) {
            return person.get();
        }

        throw new ModelNotFoundException("Invalid find person provided");
    }

}

Figura 6

ModelNotFoundException.java

Lanzará una excepción de tiempo de ejecución personalizada si el identificador de la persona no existe en la aplicación, como se puede observar la figura 7.

package com.example.jugnicaragua.jugnicaragua.exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ModelNotFoundException extends RuntimeException {
    public ModelNotFoundException(String mensaje) {
        super(mensaje);
    }

}

Figura 7

Application.properties

Spring Boot application.properties nos permite configurar la aplicación Spring Boot como se puede observar en la figura 8. Nuestra aplicación se ejecutará en el puerto 8089 conectado a una base de datos MySQL con nombre de usuario sa y contraseña sa.

server.port=8089
spring.datasource.url=jdbc:mysql://mysql-standalone:3306/jugnicaragua
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

Figura 8

Crear la imagen Docker

Creamos un nuevo archivo con el nombre Dockerfile dentro de la carpeta jugnicaragua al mismo nivel que se encuentran la carpeta src, con las instrucciones que se muestran en la figura 9. Esto es con el objetivo de construir una imagen con la versión de Java y el ejecutable de la aplicación.

FROM openjdk:11
ADD target/demo-nica.jar demo-nica.jar
EXPOSE 8089
ENTRYPOINT ["java", "-jar", "demo-nica.jar"]

Figura 9

  1. openJDK 11.
  2. Adicionamos en el directorio target el jar de la demo en este caso se llama demo-nica.
  3. En esta línea se configura el puerto de la aplicación lo colocamos el 8089.
  4. Ejecutamos el comando Java -Jar.

Desplegar la Aplicación

Creamos la Imagen Docker, usando el siguiente comando desde el directorio donde se encuentra el archivo Docker. Este comando instruye a Docker para crear la imagen de nuestra aplicación. Como se puede observar la figura 10, fueron creadas exitosamente las imágenes. 

sudo docker build -t demo-nica .


Figura 10

Si quieren verificar las imágenes creadas utilizamos el siguiente comando, y el resultado será como se puede observar en la figura 11.

docker images

Figura 11

En el siguiente paso ejecutamos el comando, con el objetivo desplegar en la máquina un contenedor docker de MySql.

sudo docker pull mysql:5.7

Para este caso, seleccionamos la versión de MySQL y podemos usar el comando de arriba. De esta manera, podemos pull de la imagen mysql-server:5.7, como se puede observar en la figura 12.

Figura 12

Desplegar el contenedor

Para desplegar el servidor de MySQL podemos usar el siguiente comando, para que funcione como un contenedor Docker.

sudo docker run --name mysql-standalone -e MYSQL_ROOT_PASSWORD=sa -e MYSQL_DATABASE=jugnicaragua -e MYSQL_USER=sa -e MYSQL_PASSWORD=sa -d mysql:5.7


Verificamos los registros de inicio de MySQL usando el siguiente comando:

docker container logs mysql-standalone

Para conectarnos al contenedor mysql, ejecutamos el siguiente comandos:

docker exec -it mysql-standalone bash -l

(Donde mysql-standalone es el nombre que se colocó al contenedor)

iniciamos sesion en MySQL con el siguiente comando, como se puede observar en la figura 13

mysql -usa -psa

Figura 13

Para verificar si está creada la base de datos JUGNicaragua, utilizamos el siguiente comando show databases; como se puede observar en la figura 14.

Figura 14

Desplegar el contenedor de la Aplicación

Ejecutamos nuestra aplicación Sprint Boot, usando los siguientes comandos:

1) mvn clean package
2) mvn compile
3) mvn install
4) docker run -d -p 8089:8089 --name demo-nica --link mysql-standanole:mysql demo-nica

Verificamos los registros de inicio del contenedor de la aplicación, usando el siguiente comando:

docker container logs demo-nica

Nota: En el caso que requieran eliminar los contenedores o imágenes de docker.

Eliminar todos los contenedores

docker rm -vf $(docker ps -a -q)

Eliminar todos las imágene

docker rmi -f $(docker images -a -q)

 

Ejecutar en POSTMAN

Crear un nuevo registro

Crear una nueva solicitud POST para crear un nuev registro de persona. Una vez que el rgsitro se crea con éxito, obtenemos el ID de la persona como respuesta. Como se puede observar en la figura 15

http://localhost:8089/save

Figura 15

Ver todas las personas registradas

Es una operación GET devuelve todas las personas registrada en la aplicación, Como se puede observar en la figura 16

http://localhost:8089/listAll

Figura 16

Repositorio

Puedes descargar el código de la aplicación desde aquí:

Conclusión

Se desarrolló una aplicación en spring boot para desplegarla por medio de un contenedor docker y conectada con una base de datos MySQL. Para la personas que quieran seguir aprendiendo pueden agregar la parte de eliminar y actualizar persona.

Referencias  

Please follow and like us:

Deja una respuesta