Conteúdo do item:

MapStruct - Salvando Dados

Vimos no vídeo anterior como responder de uma maneira mais limpa, e como a gente recebe esses dados ?

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

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

Link para @MappingTarget
https://mapstruct.org/documentation/stable/api/org/mapstruct/MappingTarget.html

Vimos no vídeo anterior como limpar o código durante uma resposta de nossa API, agora vamos ver como receber uma parte da informação

Essa classe é nossa Entrada 
import java.math.BigInteger;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class TransactionRequest {
    @Min(value = 1)
    @Max(value = 1000)
    @JsonProperty(value = "status_id")
    @NotNull
    private BigInteger statusId;

    @NotNull
    @Size(max = 250)
    private String link;

    @Size(max = 500)
    private String operatorObservation;
}

O objetivo é atualizar a tabela do meu sistema com somente alguns campos, uma atualização parcial, a Entidade abaixo é a referência dessa tabela.

import java.math.BigInteger;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonFormat;

import br.com.byiorio.api.market.MarketProductEntity;
import br.com.byiorio.api.user.UserEntity;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Table(name = "market_transactions")
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TransactionEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "market_transaction_id")
    private BigInteger id;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private UserEntity user;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column(name = "created_date")
    private Date createDate;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column(name = "finished_date")
    private Date finishedDate;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "market_products_id")
    private MarketProductEntity marketProduct;

    @Column(name = "price")
    private BigInteger price;

    @Column(name = "user_observation")
    private String userObservation;

    @Column(name = "link")
    private String link;

    @Column(name = "status_id")
    private BigInteger statusId;

    @Column(name = "operator_observation")
    private String operatorObservation;

    public String getStatusDescription(){
        return TransactionEnum.getDescriptionFromId(this.getStatusId());
    }


Seguindo a etapa mais simples o primeiro passo é carregar a nossa Entidade com os registros atuais da tabela

Optional<TransactionEntity> transactionEntityOptional = transactionRepository.findById(id);

Na sequencia teriamos que atualizar cada campo novo :
  if (transactionEntityOptional.isPresent()) {
            TransactionEntity transaction = transactionEntityOptional.get();

            // Mapeamento
            transaction.setOperatorObservation(transactionRequest.getOperatorObservation());
            transaction.setStatusId(transactionRequest.getStatusId());
            transaction.setLink(transactionRequest.getLink());

            // Salvar na tabela
            return Optional.of(transactionRepository.save(transaction));
  }


Podemos limpar o código usando o MapStruct, primeiro vamos criar a classe de mapeamento , usando a anotação "@MappingTarget" você indica qual classe você gostaria de manter os registros e alterar somente os novos registros da outra classe do parâmetro.
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;

@Mapper(componentModel = "spring")
public interface TransactionMapper {
    void updateTransactionEntity(@MappingTarget TransactionEntity entity, TransactionRequest request);
}


Voltando para o meu @Service, vou colocar um novo @Autowired

    @Autowired
    TransactionMapper transactionMapper;


Agora basta usar o novo método no lugar dos Getter e Setters:

  if (transactionEntityOptional.isPresent()) {
            TransactionEntity transaction = transactionEntityOptional.get();

            // Mapeamento
            transactionMapper.updateTransactionEntity(transaction, transactionRequest);

            // Salvar na tabela
            return Optional.of(transactionRepository.save(transaction));
  }

update;entity;mapeamento;mapper



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