Ir al contenido principal

Spring Boot y JPA añadiendo persistencia.


Código fuente del articulo:

Hola, en este tutorial vamos a ver como agregar una conexión a base de datos desde una aplicación Spring, como mapear una tabla a un Objeto y como crear un DAO(DataAacces Object) esto ultimo sin tener que escribir una sola linea de código 😤😤😤😤😤!!!. para empezar por algun lado vamos con algo ya hecho, si no estas siguiendo esta serie de tutoriales sobre Spring te recomiendo que primero leas este post donde se explica que se requiere, como se instala y como se configura un proyecto Spring Boot http://programmingbabel.blogspot.com/2017/09/crear-una-aplicacion-con-spring-boot.html. También necesitaras MySql que te lo descargase de esta url: https://dev.mysql.com/downloads/mysql/



sin mas preámbulo a lo que te truje. Si seguiste el tutorial anterior tu aplicación Spring Boot debe lucir así:


Si también hiciste el tutorial de RESTful debes tener una clase mas llamada ServicioPersonas y tu proyecto debe lucir así


para este tutorial debes tener la versión RESTful. para lo cual solo tienes que añadir una clase nueva que se llame ServicioPersonas con el siguiente código.

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ServicioPersonas {
private Map<Integer,Persona> personas;
public ServicioPersonas(){
personas= new HashMap<>();
}
@PutMapping("/put/{idPersona}")
public Persona putPersona(@PathVariable int idPersona, @RequestBody Persona persona){
personas.put(idPersona, persona);
return persona;
}
@GetMapping("/get")
    public Persona getPersona(@RequestParam("idPersona") int idPersona) {
        return personas.get(idPersona);
    }
@PostMapping("/post")
   public Persona postPersona(@RequestBody Persona persona) {
       Random r = new Random();        
       personas.put(r.nextInt(), persona);  
       return persona;
   }
@DeleteMapping("/delete/{idPersona}")
   public String deletePersona(@PathVariable int idPersona) {
       try {
          personas.remove(idPersona);
       } catch (Exception e) {
           return "Error";
       }  
       return "Listo";
 }
 
}

y ya, eso es lo bonito de las etiquetas no hay que configurar nada 😫.

Ahora si a trabajar. Primero lo primero para trabajar con bases de datos necesitas librerías de base de datos que manejen la conexión y entiendan la implementacion del lenguaje SQL según el motor de base de datos que vas a utilizar (en este caso MySQL) y necesitas librerías de Spring que se encarguen de manejar el acceso a datos, el mapeo y la creación de del DAO. Para este fin vamos a manipular el todo poderoso pom.XML y a decirle que importe todas esas librerías y las mantenga actualizadas sin que tu tengas que utilizar el cerebro. Lo aremos añadiendo tres dependencias dos para que Spring tenga acceso a datos y una para que descargue el controlador de Mysql; las dependencias serian estas:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
   </dependency>
   <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   </dependency>  
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency> 

que donde $%&$% las pongo sencillo... entre las dos bellas etiquetas que dicen <dependencies> es decir el pom.xml antes se veía así:


  Ahora se vera así:


ya tienes el 70% del problema resuelto, ahora mapearemos(esta es la traducción mas cercana a Mapping que igual esta mal escrita y no aparece en ningún diccionario ) una tabla a una clase. en este caso la tabla que vamos a mapear y el esquema al que pertenece serán los siguientes, así que tienes que ejecutar este pequeño script en la base de datos:

CREATE DATABASE `test_spring`;
use `test_spring`;
CREATE TABLE `persona` (
  `id` bigint(20) NOT NULL,
  `apellido` varchar(255) DEFAULT NULL,
  `nombre` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

quedando una clase con el siguiente código:

package com.virtuallabs.spring.entity;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="persona")
public class Persona {
    @Id
    private Long id;
    private String nombre;
    private String apellido;
    protected Persona() {}
    public Persona(Long id,String nombre, String apellido) {
    this.id=id;
        this.setNombre(nombre);
        this.setApellido(apellido);
    }    
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getApellido() {
return apellido;
}
public void setApellido(String apellido) {
this.apellido = apellido;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
@Override
public String toString() {
return "Persona [id=" + id + ", nombre=" + nombre + ", apellido=" + apellido + "]";
}
}

que tiene tres anotaciones algo extrañas:

@Entity: esta etiqueta indica que esta clase representa una tabla de la base de datos
@Table(name="persona"): esta anotación se utiliza para reafirmar el nombre de la tabla que estamos representando con la clase, la clase se puede llamar Ramiro pero esta anotación indicara que corresponde a la tabla persona.
@Id: en JPA toda entidad necesita un Id por cuestiones de Cache y otros conceptos mas avanzados que maneja, el id mas simple es un numero entero en la tabla, algunas anotaciones extra permiten crear llaves compuestas y generar numeradores si el motor de base de datos lo soporta.

Ahora tendrás una proyecto que lucirá así:

Ya tienes mapeada la tabla pero no le has dicho a Spring a que base de datos conectarse, eso lo haremos creado un archivo application.properties en el paquete main.resources. Es importante que no cambies este nombre y esta ubicación, porque Spring por defecto revisara estas rutas: el contenido del archivo application.properties sera el siguiente:

spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/test_spring
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.tomcat.max-wait=20000
spring.datasource.tomcat.max-active=50
spring.datasource.tomcat.max-idle=20
spring.datasource.tomcat.min-idle=15
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.id.new_generator_mappings = false
spring.jpa.properties.hibernate.format_sql = true
logging.level.org.hibernate.SQL=ALL
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE 

Aquí por defecto el usuario y la contraseña serán root que son las que mysql trae por defecto, en este punto tu proyecto se vera así:




Ya esta la conexión y la tabla. solo falta el DAO para manejar las operaciones y esto es lo bueno de Spring y es que estas operaciones ya están pre-implementadas y con extender una interfaz ya tenemos todo el problema resuelto, para que lo veas vamos a crear la siguiente interfaz:

package com.virtuallabs.spring.repository;

import org.springframework.data.repository.CrudRepository;
import com.virtuallabs.spring.entity.Persona;

public interface PersonasRepository extends CrudRepository<Persona, Long> {
}

y listo 😎, Spring entiende que esto es un repositorio es decir que maneja las operaciones de inserción, actualización y borrado de la tabla que esta como primer argumento en el tipo genérico en este caso Persona <Persona, Long> el segundo argumento es el tipo de llave en este caso el Id de la tabla es un simple numero un Long.

en este punto tu proyecto lucirá así:


Ya tenemos todo y solo falta utilizarlo. Para usarlo en la clase ServicioPersonas inyectaremos el repositorio de personas con el siguiente codigo

@Autowired 
private PersonasRepository personasRepository;

que de raro tiene una etiqueta @Autowired , esta quiere decir que vamos a traer un recurso y que este recurso no requiere parámetro alguno para poder crearse. ahora en método putPersona  vamos a utilizar el repositorio para guardar en la base de datos cada persona que nos envíen.
con solo dar . y ctrl+espacio podrás ver todo lo que ofrece el repositorio por defecto:

en este caso vamos a utilizar la función save, dejando el método de la siguiente forma:

@PutMapping("/put/{idPersona}")
public Persona putPersona(@PathVariable int idPersona, @RequestBody Persona persona){ com.virtuallabs.spring.entity.Persona person= new com.virtuallabs.spring.entity.Persona(new Long(idPersona), persona.getNombre(), persona.getApellido());
personasRepository.save(person);
return persona;
}
Este ejemplo tiene algo confuso y es que tanto la entidad como el Objeto con el que estoy negociando en los servicios tienen el mismo nombre por eso utilizo toda la descripción del paquete para el objeto de la base de datos. 

sin mas tu proyecto se debe ver así:


ahora a ejecutar y a probar, para probar te recomiendo instalar un complemento de google chrome llamado Advanced REST client 


Para lanzar la aplicación sigue las siguientes tres imágenes.



 Ahora desde el Advanced REST client lanzaremos la siguiente petición al método PUT


   respuesta

Y listo como veras en la base de datos quedara tal una Maria Perez con id 1. ahora solo te queda implementar los otros métodos según corresponda y ya tendrás un servicio RESTful con persistencia. Gracias por leer este tutorial ;).

Comentarios

Entradas populares de este blog

Conectarse al LDAP (directorio activo) utilizando JAVA

Un LDAP es un sistema de autenticación estándar utilizado por muchas compañías para controlar el acceso a aplicaciones y recursos. Por lo general se espera que cualquier nueva aplicación haga uso del LDAP para realizar la autenticación y controlar los permisos en forma unificada, la seguridad es transversal a todos los procesos que realiza una organización. Una vez regado el cuento a lo que vinimos, como conectarse a un LDAP. Lo primero que debes saber es que no se requieren librerías adicionales, JAVA en su distribución estandar ya cuenta con todo lo que necesitas. primero tres siglas que tienes que tener en cuanta. CN  = Common Name OU  = Organizational Unit DC  = Domain Component Para conectarse primero necesitas es instanciar un Objeto de la clase LdapContext, este se encargara de manejar la conexión al LDAP y las peticiones que se hagan al mismo. por consiguiente necesitara que le entregues una serie de propiedades de conexión. Esto lo haras con un Map de la siguiente

Clases anónimas JAVA (Anonymous Classes)

Código fuente articulo: https://www.dropbox.com/s/pzw44ot0ji2metl/Lambda.zip?dl=0 Las Clases anónimas en JAVA son una solución rápida para implementar una clase que se va utilizar una vez y de forma inmediata. Por ejemplo el  EventHandler  para un botón se puede implementar en la misma asignación valiendonos de la interfaz  EventHandler  que ya esta definida. Pero mejor vamos con un ejemplo mas simple. De la definición anterior concluimos dos cosas la primera es que para crear una clase anónima es necesario haber definido una interfaz, una clase o una clase abstracta. La clase anónima lo que hará sera implementar la interfaz definida o sobre escribir los métodos definidos. Para ilustrar esto utilizaremos el ejemplo del JAVA Tutorial https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html . en este ejemplo tenemos que implementar clases que cumpliendo con la interfaz Saludo sean capaces de saludar en diferentes idiomas. El paso uno sera definir la int

Paralelismo en JAVA Executors (ExecutorService, Callables y Futures).

Código fuente articulo: https://www.dropbox.com/s/jci67120hmd0uce/Paralelismo.zip?dl=0 Para manejo de concurrencia Java desde la versión 5 presento el Concurrency API  este presento una mejora substancial en el manejo de hilos y procesos en paralelo, antes solo contabas con Thread y Runnable. lo que te obligaba a controlar la creación y el numero de hilos de ejecución, no te entregaba un resultado del procesamiento y no te dejaba controlar las Excepciones que lanzara un hilo...un hilo se lanzaba y amenos que le enviaras un un CallBack perdías todo contacto con el. Para solucionar este problema se crearon dos tipos de objetos Callables y Futures. estos dos te permiten encapsular una tarea asignándole un tipo de Objeto que sera el valor de retorno y hacer seguimiento a las tareas que ejecuto en paralelo pudiendo preguntar si ya termino, que resultado lanzo y que excepciones ocurrieron. Arranquemos con la implementación de Callable, Callable es una interfaz que te permite defini