5 Nisan 2021 Pazartesi

MapStruct @Mapper Anotasyonu - Arayüzün Üstüne Yazılır

Giriş
Örnek
Şöyle yaparız. Burada INSTANCE alanı da kullanılarak CarMapper arayüzüne erişim daha kolay hale getiriliyor.
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper
public interface CarMapper {
    CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );

    CarDTO carToCarDto(Car car);
}
Örnek - Target İçindeki Alanı Parametre Geçmek
Elimizde şöyle bir kod olsun
class Foo {
  int field1;
}
class Bar {
  int field1;
  int sourceDevice;
}
Şöyle yaparız. Burada Bar içinde sourceDevice alanı metoda parameter olarak geçildiği için sorun olmuyor.
@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR)
public interface FooMapper {
FooMapper INSTANCE = Mappers.getMapper(FooMapper.class);

Bar toBar(Foo foo, int sourceDevice);
}
componentModel Alanı
Açıklaması şöyle
Bonus Tip : There can be such cases where you need to perform some complex logic while mapping a field like Autowiring some other bean to your Mapper to get some information like active spring profiles by Autowiring Environment bean. In such cases you can’t use Interface as your mapper. Instead, use an Abstract class to declare your mapping methods as abstract methods.
Örnek - cdi
Şöyle yaparız
@Mapper(componentModel="cdi", injectionStrategy=InjectionStrategy.CONSTRUCTOR)
@Mapper(componentModel="spring", injectionStrategy=InjectionStrategy.FIELD)
Örnek - spring
Şöyle yaparız. Üretilen koda @Component anotasyonu eklenerek Spring bean'i olması sağlanır.
@Mapper(componentModel = "spring")
public interface DoctorMapper {
   DoctorDto toDto(Doctor doctor);
}
Örnek
Şöyle yaparız
@Mapper(componentModel = "spring")
public interface StudentMapper {
  StudentDto toDto(Student student);
}
Üretilen kod şuna benzer
import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-11-24T14:41:11+0100",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_251
(Oracle Corporation)"
)
@Component
public class StudentMapperImpl implements StudentMapper {

  @Override
  public StudentDto toDto(Student student) {
    if ( student == null ) {
      return null;
    }

    StudentDto studentDto = new StudentDto();

    studentDto.setFirstname( student.getFirstname() );
    studentDto.setLastname( student.getLastname() );

    return studentDto;
  }
}
implementationPackage Alanı
Örnek
Şöyle yaparız. Üretilen kod "target/generated/sources/annotations/mapper/impl/" altına yerleştirilir.
@Mapper(implementationPackage = "mapper.impl")
public interface UserMapper {

  UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

  User userDTOtoUser(UserDto userDto);

  @InheritInverseConfiguration
  UserDto userToUserDTO(User user);
}
Kullanmak için şöyle yaparız
UserDto userDto = ...;
User user = UserMapper.INSTANCE.userDTOtoUser(userDto);
typeConversionPolicy Alanı
Açıklaması şöyle
Converting from larger data types to smaller ones (e.g. from long to int) can cause a value or precision loss. The Mapper annotation has a method typeConversionPolicy to control warnings / errors.
unmappedTargetPolicy Alanı
Eğe target sınıfın bir alanına değer atanmıyorsa, ne yapılacağını belirtir.
Örnek
Şöyle yaparız. Derleyici kodu derlemez.
@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR)
public interface CarMapper {
   ...
}
uses Alanı
Not : uses alanını kullanmak istemiyorsakuses Alanı Seçeneği Yerine DTO yazısına bakabilirsiniz.

Örnek
Doctor sınıfında Address alanı varsa ve bunu DoctorDto sınıfındaki AddressDto alanına map'lemek istiyorsak şöyle yaparız
@Mapper(
      componentModel = "spring",
      unmappedTargetPolicy = ReportingPolicy.ERROR,
      uses = {AddressMapper.class})
public interface DoctorMapper {

   @Mapping(source = "phone", target = "contact")
   @Mapping(source = "speciality.name", target = "specialityName")
   DoctorDto toDto(Doctor doctor);
}
AddressMapper tabii ki bir Mapper olmalı. Şöyle yaparız
@Mapper(componentModel = "spring")
public interface AddressMapper {
   AddressDto toDto(Address address);
}

Hiç yorum yok:

Yorum Gönder