No hice caso al viajero del tiempo de no tratar de implementar la Aplicación en Inglés desde el principio 😃
A rehacer, mejor más aprendemos!
Antes de empezar
¿Qué es y qué usaremos de Spring?
¿Java sigue siendo gratuito?
Instalación de ambiente de desarrollo: Windows
Instalación de ambiente de desarrollo: Linux Ubuntu
Instalación de ambiente de desarrollo: macOS
Introducción a Spring boot
Creando aplicaciones autocontenidas con Spring Initializr
Hola mundo con Spring Boot
Configurar Spring Boot
Crear la estructura del proyecto
Spring Data
¿Qué es JPA?
Conocer qué es Spring Data
Conectar la base de datos a nuestra aplicación
Mapear las tablas como clases
Crear Entity cuando su clave primaria es compuesta
Mapear relaciones entre clases
Usar la interface CrudRepository
Query Methods
Construyendo nuestra API
Implementar la anotación @Repository
¿Qué es el patrón Data Mapper y qué resuelve?
Orientar nuestra API al dominio con MapStruct
Orientar nuestro repositorio a términos del dominio
Inyección de dependencias
Implementar la anotación @Service
Implementar la anotación @RestController
Exponer nuestra API
Mejorando nuestra API
Controlar las respuestas HTTP
Crear el dominio de compras
Mapear el dominio de compras
Crear el repositorio de compras
Probando nuestros servicios de compras
Documentar nuestra API con Swagger
Despliegue de nuestra aplicación
Desplegar nuestra API desde la ventana de comandos
Desplegar nuestra base de datos con Heroku
Desplegar nuestra API con Heroku
Conclusiones y despedida del curso
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Alejandro Ramírez
Aportes 57
Preguntas 31
No hice caso al viajero del tiempo de no tratar de implementar la Aplicación en Inglés desde el principio 😃
A rehacer, mejor más aprendemos!
Esto del mapper, si me revento la cebeza
Excelente! Me impresiona la manera en la que mapstruct simplifica el código.
En java antes de saber que existe mapStruct usaba ModelMapper,
el uso es mas simple en modelMapper si se trata de convertir clases con atributos con el mismo nombre por ejemplo de Categoria a CategoriaDto con los mismos atributos, veo que con mapStruct la configuracion es mucho más simple para indicar por ejemplo en este caso atributo con atributo de diferente nombre.
A alguien mas al compilar les dice que productos no está dentro de categoria?
Bendito viajero del tiempo.
Creación de paquete llamado “mapper” en el paquete “persistence”.
Se crean como interface
A cada clase se le añade el sufijo “Mapper”.
Se le añade a la clase la anotación @Mapper
MapStruct nos ofrece una integración con Spring. Se le especifica a la anotación: @Mapper(componentModel = "spring")
Se especifica la conversión: Category toCategory(Categoria categoria);
. Se convertirá un entity de tipo Categoria a un dominio de tipo Category.
Se añade la siguiente estructura de anotaciones:
@Mappings({
@Mapping(source = "idCategoria", target = "categoryId"),
@Mapping(source = "descripcion", target = "category"),
})
Category toCategory(Categoria categoria);
Se debe hacer el mapeo en sentido contrario. Con la anotación @InheritInverseConfiguration
@Mapping(target = "productos", ignore = true)
@InheritInverseConfiguration
@Mapping(target = "productos", ignore = true)
Categoria toCategoria(Category category);
Cuando se mapea un atributo que es de una clase que tiene su mapper propio, dentro de la anotación @Mapper, se añade algo como lo siguiente: @Mapper(componentModel = "spring", uses = {CategoryMapper.class})
Muy buen aporte! Ejemplos muy útiles para aprovechar mapstruct.
Codigo de la clase
@Mapper(componentModel = "spring")
public interface CategoryMapper {
@Mappings({
@Mapping(source = "idCategoria", target = "categoryId"),
@Mapping(source = "descripcion", target = "category"),
@Mapping(source = "estado", target = "active"),
})
Category toCategory(Categoria categoria);
@InheritInverseConfiguration
@Mapping(target = "productos", ignore = true)
Categoria toCategoria(Category category);
}
para ignorar un atributo se escribe el siguiente codigo , se ignora los campos que se relacciona con otras tablas o campos que no necesitemos, siempre se debe ignorar si no se agrega en los campos Mappings
@Mapping(target = "nombreCampo", ignore = true)
Si les marca error al hacer el mapeo de categorias y productos a mi me lo soluciono el poner los setters y getters
Tengo entendido que a la hora de crear Interfaces es buena practica anteponer una i mayúscula, para denotar que se trata de una interfaz y no una clase.
Algo así
Interface: ICategoryMapper -> fijense en la (i) que viene primero.
Para los que tengan problemas con el @Data de lombok, nn vez de usar @Data se deben usar @Getter y @Setter, así el lombok no genera problemas.
Adicional colocar annotationProcessor:
implementation 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.22'
Dudo mucho que en un proyecto real exista el espanglish que hay metido aqui, esto es un desastre, en mi opinion 😦
@Mapper(componentModel = "spring", uses = {CategoryMapper.class})
public interface ProductMapper {
@Mappings({
@Mapping(source = "idProducto", target = "productId"),
@Mapping(source = "nombre", target = "name"),
@Mapping(source = "idCategoria", target = "categoryId"),
@Mapping(source = "precioVenta", target = "price"),
@Mapping(source = "cantidadStock", target = "stock"),
@Mapping(source = "estado", target = "active"),
@Mapping(source = "categoria", target = "category"),
})
Product toProduct(Producto producto);
List<Product> toProducts(List<Producto> productos);
@InheritInverseConfiguration
@Mapping(target = "codigoBarras", ignore = true)
Producto toProducto(Product product);
}
Para indicarle a Spring que tiene que pasar el campo categoria a Category debe usar CategoryMapper.class
@Mapper(componentModel = "spring", uses = {CategoryMapper.class})
Si las variables se llaman igual, no es necesario hacer el @Mapping. La utilidad sería entonces por ejemplo no mapear algunas variables (en este caso el código de barras, por ejemplo).
A veces algunas columnas se llaman igual y otras no, por ejemplo “email” a veces lo llaman igual en bases de datos en español, entonces no sería necesario hacer el mapping de esta.
Buenas no me carga el vídeo 22, pase al vídeo 23 y funciona perfecto
Es normal que en este punto si ejecuto la aplicacion obtenga el siguiente error:
error: No property named “idCreacion” exists in source parameter(s). Did you mean “null”?
@Mapping(source = “idCreacion”, target = “id”)
Cabe recalcar que estoy usando otra base de datos y por ende otras entidades, sin embargo me he guiado completamente del curso, cambiando solo el nombre o tipo de variable
La primera vez que lo vi no entendi mucho, pero me tome un break regrese y lo vi a 0.85x y lo entendi todo.
MaspStruct es muy útil cuando se trabaja en proyectos pequeños, pero ya cuando nos enfrentamos a proyectos más grandes, se puede tornar confuso y difícil de mantener. También encontré algunos problemas de compatibilidad con las versiones actuales, ya que han venido cambiando la forma de hacer este mapper, sobre todo en la 1.5.2, ya que no es muy amigable con spring y las entity.
La anotación @Mappings no es necesaria (al menos en versiones recientes). Por ejemplo, en el mapper de productos pueden tener lo siguiente:
@Mapping(source = "idProducto", target = "productId")
@Mapping(source = "nombre", target = "name")
Product toProducto(Producto producto)
dfghdgfhdf
Hola Alejandro, no resulta el mapstruct con vsc, pero si con intellij… sabes o alguien sabe como poder habilitarlo para vsc…?
Gracias 😃
al compilar spring no encuentra el mapper con autowired . alguien tiene ese error ?
Vamos a crear los mappers para transformar los categories en categorias y products en productos, es como hacer un puente entre las definiciones de entitis
MapStruct es bastante fiable, me faltaban algunos getters/setters de las clases y el compilador es bastante específico con lo que hace falta, bastante útil en caso de hacer refactoring para algún property que suele pasar aunque de todas formas haya que hacer los ajustes en los strings que definen las relaciones
Me encanta que Spring Boot no reinveta la rueda y 99% de las cosas que se ocupan en el backend ya están hechas, simplemente es saber como usar bien las anotaciones y la inyección de dependencia
No me quedo claro como es que esto:
@Mapping(source = “categoria”, target = “category”)
Sabe que tiene que usar este mappeador?
uses = {CategoryMapper.class}
No veo donde se haga la relacion entre los nombres category y CategoryMapper.class.
y si la bd esta en ingles … y las clases en ingles…se necesita igual mapear?..
Es importante que todas las variables que están en los entitys tengan getter and setter, si no después no compilaran.
Sigo sin entender la función del mapping, mejor de una vez los nombres en ingles no? Y nos ahorramos todo esto.
Genial! lo que yo solía hacer (hasta ahora) era crear una clase entidad para la persistencia de los datos y creaba dos clases aparte para las peticiones y las respuestas de este objeto para la API.
✅
✅
Chale todo hiba bien hasta esta clase 🥲😭, hay que hacer ajustes para que compile el proyecto
Muy bien explicado todo.
Hermoso como me simplificó todo el código de mappeo de DTO a Entity y viceversa en mis proyectos personales y en el trabajo. Muchísimas gracias.
Quien tenga problemas con @Mapper y el plugin, es porque a partir de la version 1.5.0 de Mapstruct el pluggin omitio esta anotacion, por eso instalen la version 1.3.0
Que genial clase. Este tema en especial, me voló el cerebro. Párrafo aparte para el profesor, que es un genio y explica muy bien.
¿Y quépasa con los java expressions y los imports? ¿y los decoradores?
Mapear los entity a las objetos de dominio (Hacer el traductor entre la capa de la persistencia y la capa de dominio=
Mapear atributos que son clases.
Enorme diferencia en simplicidad con respecto a ModelMapper
Para que sirve agregar este metodo?
List<Product> toProducts(List<Producto> productos);
y porque en categoria no hicimos algo parecido?
A alguien mas no le carga este video?
Si estás usando lombok debes incluir el annotationProcessor para que te funcione el mapper.
dependencies {
...
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?