Conteúdo do item:

MapStruct - Respondendo uma requisição

Biblioteca para passar valores de DTOS para os Entities.

Link oficial da biblioteca:
https://mapstruct.org/

Link sobre diferentes bibliotecas e performance:
https://www.baeldung.com/java-performance-mapping-frameworks

Link para mapear campos diferentes
https://mapstruct.org/documentation/stable/api/org/mapstruct/Mappings.html

Link para todas as funções
https://mapstruct.org/documentation/stable/reference/html/

Para que serve?

Em muitos projetos temos os mapeamentos da tabela do banco de dados em classes, que chamamos de Entity, porem temos as nossas APIS que recebem ou devolvem informações, para interagir com o nosso Banco de Dados, e nem sempre queremos devolver todas as informações das tabelas, nesses casos criamos os DTOS com as informações que gostaríamos de devolver, e para isso precisamos mapear as informações do Entity para os DTO, onde dão um pequeno trabalho,  e podemos fazer o mesmo trabalho com um mapeamento automático utilizando o MapStruct.

Instalando no projeto

Vamos criar uma variável de versão do MapStruct no pom.xml, dentro do properties do projeto, para que possamos utilizar nas Tags de dependências e build. Como estou usando o Lombok eu irei colocar a configuração dele também.

<org.mapstruct.version>1.5.0.Final</org.mapstruct.version>
<org.projectlombok.version>1.18.22</org.projectlombok.version>

Ficando assim

	<properties>
		<java.version>16</java.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<maven.compiler.target>16</maven.compiler.target>
		<maven.compiler.source>16</maven.compiler.source>
		<org.mapstruct.version>1.5.0.Final</org.mapstruct.version>
		<org.projectlombok.version>1.18.22</org.projectlombok.version>
	</properties>

Na sequência dentro da Tag de Build, iremos adicionar um novo plugin de compilação para que durante o build  maven execute alguns processos, caso já tenha esse plugin configure somente os annotationProcessorPaths. No exemplo abaixo coloquei para ele reconhecer o Lombok e o MapStruct em conjunto.

	<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${maven.compiler.source}</source>
					<target>${maven.compiler.target}</target>
					<annotationProcessorPaths>
						<path>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
							<version>${org.projectlombok.version}</version>
						</path>
						<!-- This is needed when using Lombok 1.18.16 and above -->
						<path>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok-mapstruct-binding</artifactId>
							<version>0.2.0</version>
						</path>
						<path>
							<groupId>org.mapstruct</groupId>
							<artifactId>mapstruct-processor</artifactId>
							<version>${org.mapstruct.version}</version>
						</path>
					</annotationProcessorPaths>
				</configuration>
			</plugin>

Pegando como exemplo o meu projeto, o BUILD ficou assim:

<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${maven.compiler.source}</source>
					<target>${maven.compiler.target}</target>
					<annotationProcessorPaths>
						<path>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
							<version>${org.projectlombok.version}</version>
						</path>
						<!-- This is needed when using Lombok 1.18.16 and above -->
						<path>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok-mapstruct-binding</artifactId>
							<version>0.2.0</version>
						</path>
						<path>
							<groupId>org.mapstruct</groupId>
							<artifactId>mapstruct-processor</artifactId>
							<version>${org.mapstruct.version}</version>
						</path>
					</annotationProcessorPaths>
				</configuration>
			</plugin>
		</plugins>
	</build>

Utilizando dentro do Spring

Como criar esses mapeamentos junto ao Spring?

Primeiro criamos uma interface com a anotação @Mapper, nessa interface colocamos todos os métodos de conversão de um Entity específico para um DTO desejado. No caso abaixo quero converter meu BlogEntity para um BlogBaseResponse. Estou utilizando o parâmetro componentModel = "spring"  para avisar ao Spring que gostaria de uitilizar o seu gerenciamento de bean.

package br.com.byiorio.api.blog;

import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface BlogEntityMapper {
    BlogBaseResponse toBlogBaseResponse(BlogEntity blogEntity);
}

Depois desse mapeamento podemos fazer um @Autowired para criar uma instância da interface

@Autowired
private BlogEntityMapper blogEntityMapper;

Uma vez criado a variável é só utilizar

	@GetMapping(path = "/", produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<List<BlogBaseResponse>> allBlogs() {

		Iterable<BlogEntity> lista = blogService.findPubFetchingAll();

		if (!lista.iterator().hasNext()) {
			return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
		} else {
			List<BlogBaseResponse> listResp = new ArrayList<>();

			Iterator<BlogEntity> iter = lista.iterator();
			while (iter.hasNext()) {
				listResp.add(blogEntityMapper.toBlogBaseResponse(iter.next()));
			}

			return ResponseEntity.ok(listResp);
		}
	}


O código foi alterado de:

while (iter.hasNext()) {
	BlogEntity item = iter.next();

	if (item != null) {
		BlogBaseResponse resp = new BlogBaseResponse();
		resp.setTitle(item.getTitle());
		resp.setId(item.getId());
		listResp.add(resp);
	}
}

para:

while (iter.hasNext()) {
	listResp.add(blogEntityMapper.toBlogBaseResponse(iter.next()));
}


Assista o vídeo para ter uma melhor visão de como utilizar essa biblioteca. 

mapper; mapeamento; DTO; bean;lombok;



Redirecionar para https://www.byiorio.com.br/product/4/item/28