Toilet paper #106

Bevor ich hier den Depp mach', nehm' ich lieber MapStruct

Problem

Eine ungeliebte und fehleranfällige, aber (vor allem in Mehrschichtenarchitekturen) wiederkehrende Aufgabe ist das Schreiben von Mapperklassen für ähnliche Objekte, z.B. zwischen Datenbankentitäten und Request/Response-DTOs. Auch das Schreiben von Unit Tests für solche Mapper ist mühsam.

Lösung

Die Java-Library MapStruct (http://mapstruct.org) nimmt einem diese Aufgabe ab, indem sie Annotations-basiert automatisch Mapping-Code generiert.

Vorteile:

  • Generierung zur Compile-Zeit: kein Einfluss auf Performance
  • Generierter Code nutzt Getter/Setter-Methoden, ist daher typensicher, leicht zu debuggen und einfach zu verstehen/ erweitern
  • Sinnvolle Default-Konventionen, Verhalten kann leicht überschrieben werden

Beispiel

Zwei komplementäre Klassen (Getter/Setter-Methoden nicht gezeigt):

public class CupOfCoffee {
    private Enums.Brand brand;
    private double temperature;
    private int volume;
    private double milk;
    private double sugar;
    private boolean isCorretto;
}
public class CupOfCoffeeDTO {
    private String brand;
    private String temperature;
    private int volumeOfCup;
    private double milk;
    private double sugar;
    private boolean isCorretto;
}

MapStruct-Basisklasse:

@Mapper(componentModel = "spring")
public abstract class CoffeeMapper {
    @Mapping(source = "volume", target = "volumeOfCup")
    @Mapping(source = "temperature", target="temperature", numberFormat = "$#.0")
    public abstract CupOfCoffeeDTO toCupOfCoffeeDTO(CupOfCoffee entity);

    @InheritInverseConfiguration
    public abstract CupOfCoffee toCupOfCoffee(CupOfCoffeeDTO dto);
}

Beim Kompilieren generiert MapStruct den Mapping-Code entsprechend den Annotationen. Die expliziten @Mapping-Annotationen sind nur für nicht-triviale Mappings (z.B. bei unterschiedlichen Variablennamen, Zahlenformaten etc.) nötig. Die abstrakte Klasse kann noch um eigene Mapping-Funktionen erweitert werden.

Obacht:

  • nach jeder Änderung der abstrakten Mapper-Klasse muss neu kompiliert werden
  • funktioniert in Verbindung mit Lombok (ein weiterer annotationsbasierter Codegenerator) manchmal nicht ganz reibungslos
Toilet paper #106: MapStruct

Wir verwenden Cookies, um unsere Webseite für Sie zu optimieren. Mit dem Besuch unserer Webseite erklären Sie sich damit einverstanden. // Our website is using cookies to improve your experience. By continuing to browse the site, you are agreeing to our use of cookies.

Weitere Informationen finden Sie in unserer Datenschutzerklärung. // For more information, please refer to our privacy policy.