Cómo mapear objetos en Java con MapStruct

¿Qué es MapStruct?

MapStruct es una herramienta que nos permite, mediante anotaciones crear mapeos entre objetos en tiempo de compilación. Evitando tener que escribir todo el código de mapeo a mano, está pensado para funcionar con Java 1.6 o posterior.


Añadir MapStruct a nuestro proyecto

Ahora veremos cómo incluir MapStruct en un proyecto con Maven, simulando conversiones entre objetos y objetos DTO, tal y como sucedería en una arquitectura REST.


Para añadir MapStruct añadimos la siguiente dependencia a nuestro proyecto:


Actualizamos los índices de Maven y con esto ya tenemos MapStruct listo para usarlo en nuestro proyecto, ahora veremos un ejemplo práctico.


Ejemplo con Java

Ahora vamos a crear una clase llamada Address y otra AddressDTO, que nos servirán para realizar los diferentes mapeos, vamos a crear varios ejemplos de mapeo por lo que iremos cambiando los atributos de las clases para cada ejemplo.


Ejemplo 1: Clases a mapear con los mismos atributos, tipos y nombres iguales.

En este primer ejemplo, veremos el caso más sencillo, en el que nuestra clase y nuestro DTO, tienen lo mismos campos, con los mismos tipos y los mismos nombres. Ambas clases tienen sus métodos getters, setters y constructor.



Una vez tenemos nuestras clases creadas, vamos a crear nuestro Mapper, que puede ser una interfaz o una clase abstracta, en este ejemplo utilizaremos la interfaz. 




Una vez tenemos esta interfaz creada, necesitamos que al compilar nuestro proyecto Maven nos genere la implementación de la clase, nos vamos al pom.xml y en pluginManagement ponemos lo siguiente:




Ahora creamos una prueba unitaria para comprobar que funciona nuestro converter:


En el test creamos el objeto Address a convertir y el objeto AddressDTO que nos tendría que devolver para comprobar qué funciona correctamente, a su vez en el test hemos ‘instanciado’ el converter haciendo uso deMapStruct, con el método getMapper(). Ahora ejecutamos en nuestra terminal mvn clean verify y el test debería pasarnos, si vamos a la carpeta target, podemos ver la implementación de nuestro converter y lo que hace MapStruct por debajo.


Bien, hasta ahora hemos visto como mapear objetos idénticos, pero, ¿qué ocurre si tenemos los mismos tipos de atributos pero algunos con nombres distintos?


Ejemplo 2: Clases a mapear con los mismos atributos, tipos y algunos nombres diferentes.


Con la misma configuración de antes, dejamos la clase Address tal cual está, vamos a cambiar solo nuestra clase DTO, y vamos a dejarla así:


Como vemos, solo hemos cambiado de nombre los atributos phone -> phoneNumber y name -> personName, ahora si ejecutamos de nuevo nuestro test, fallará. Esto se debe a que MapStruct no está pudiendo realizar un mapeo directo, vamos a la interfaz y lo solucionamos de la siguiente manera:

De esta forma estamos diciéndole a MapStruct, que el atributo phone de Address, tiene que ser mapeado al atributo phoneNumber de AddressDTO, y lo mismo con name, como vemos es muy sencillo, pero que pasa si dentro del objeto a convertir tengo otro objeto que también necesita conversión, vamos a verlo en el tercer ejemplo:


Ejemplo 3: Clases a mapear con los mismos atributos, diferentes tipos y nombres iguales.


Vamos a poner los atributos de name, lastname y phone, dentro de un objeto llamado Person, y crearemos también un PersonDTO, vemos como quedarían nuestras clases:

Bien, ahora cambiamos nuestro test, para poder probar también los datos dentro del objeto Person:

Si ejecutamos esto, nuestros tests pasarán sin cambiar nada enMapStruct, porque es lo suficientemente ‘listo’ como para crear un mapeo directo entre Person y PersonDTO, pero si esos objetos fueran más complejos o tuviera dificultades MapStruct para mapearlos, podemos crear un método en la interfaz de esta forma:


O si la conversión fuera demasiado compleja, a partir de Java 8, podemos hacer uso de los métodos default en las interfaces y crear nosotros mismos a mano la conversión, pero esto solo en casos necesarios.


Conclusión

Como vemos, crear mapeos entre objetos con MapStruct es muy sencillo, también nos permite crear mapeos con objetos con herencia, con listas anidadas, etc, etc. Pero para todo ello ya existe la documentación de MapStruct en el siguiente enlace: MapStruct reference guide


Espero que te haya gustado este tutorial, nos vemos en el siguiente 🙂

29 vistas

©2020 por Juanma Perez.