Bean-Mapping mit MapStruct



Ähnliche Dokumente
Einfache Bean-Mappings mit MapStruct 1.2

Bean Mappings mit MapStruct 1.2

WER ERZÄHLT DIE NÄCHSTEN 55+ MINUTEN ETWAS?

Bean-Mapping mit MapStruct

Gebundene Typparameter

Typumwandlungen bei Referenztypen

Objektorientierte Programmierung. Kapitel 12: Interfaces

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

Java: Vererbung. Teil 3: super()

Auszug aus JAX-WS Folien

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Java Einführung Umsetzung von Beziehungen zwischen Klassen. Kapitel 7

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Testen mit JUnit. Motivation

Einführung in die Programmierung

Java Einführung Abstrakte Klassen und Interfaces

Klausur zur Einführung in die objektorientierte Programmierung mit Java

Kapitel 12: Übersetzung objektorienter Konzepte

WebService in Java SE und EE

Objektorientierte Programmierung

Programmieren I. Strategie zum Entwurf von Klassen. Beispiele. Design von Klassen. Dr. Klaus Höppner. Beispiel: Bibliothek

Prinzipien Objektorientierter Programmierung

Algorithmen und Datenstrukturen

3 Objektorientierte Konzepte in Java

Tutorium Rechnerorganisation

Einführung in Javadoc

Einführung in die Programmierung für Wirtschaftsinformatik

Javakurs zu Informatik I. Henning Heitkötter

Große Übung Praktische Informatik 1

C# im Vergleich zu Java

Programmieren in Java

Nathan Burgener. Design by Contract. Modul SWE

Java-Schulung Grundlagen

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Java Einführung Collections

Software Engineering. Zur Architektur der Applikation Data Repository. Franz-Josef Elmer, Universität Basel, HS 2015

Javakurs 2013 Objektorientierung

Programmiervorkurs WS 2012/2013. Schleifen und Methoden

Objektorientierte Programmierung

Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala

Der lokale und verteilte Fall

Software-Engineering und Optimierungsanwendungen in der Thermodynamik

Remote Method Invocation

Eclipse Plugins für die komfortablere Verwendung von ibatis SQLMaps

Java Reflection. Meta-Programmierung mit der java.lang.reflection API. Prof. Dr. Nikolaus Wulff

5. Abstrakte Klassen. Beispiel (3) Abstrakte Klasse. Beispiel (2) Angenommen, wir wollen die folgende Klassenhierarchie implementieren:

Rekursion. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Software Engineering Klassendiagramme Einführung

13. Tutorium zu Programmieren

Programmieren. 10. Tutorium 4./ 5. Übungsblatt Referenzen

Java Einführung Packages

Dieses Tutorial gibt eine Übersicht der Form Klassen von Struts, welche Besonderheiten und Unterschiede diese aufweisen.

Software Engineering Klassendiagramme Assoziationen

Java Beans. von Raoul Schneider

4. AuD Tafelübung T-C3

1 Polymorphie (Vielgestaltigkeit)

5. Abstrakte Klassen

Java Kurs für Anfänger Einheit 5 Methoden

EJB Beispiel. JEE Vorlesung 10. Ralf Gitzel

Objektorientierte Programmierung

RESTful Web. Representational State Transfer

Schedulingund Thread-Ausführer

Übungsaufgabe Transaktion als Middleware

Vererbung & Schnittstellen in C#

Kapitel 6. Vererbung

How To Einbinden von Kartendiensten in eine Java Applikation mit Hilfe des JXMapKit

Projekt AGB-10 Fremdprojektanalyse

Folge 18 - Vererbung

Themen. Web Service - Clients. Kommunikation zw. Web Services

Client-Server-Beziehungen

Das Model View Controller (MVC) Konzept

Workshop Java Webentwicklung Einführung in Hibernate. Ulrich Stärk

Oliver Paulus, 7. Februar Spring Framework Einführung. Oliver Paulus, Was ist Spring?

Einführung in die Java- Programmierung

Innere Klassen in Java

Objektbasierte Entwicklung

Einfache Arrays. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Einführung in Java. PING e.v. Weiterbildung Andreas Rossbacher 24. März 2005

Steffen Hofmann Freie Universität Berlin ZEDAT Identity and Customer Management (ICM) Aktueller Stand Shibboleth IdP3

Test-Driven Design: Ein einfaches Beispiel

Design Patterns 2. Model-View-Controller in der Praxis

Programmierkurs Java

Struts 2 Das Imperium schlägt zurück?

Einführung in die Programmierung für NF

Java Web Services Metadata JSR-181

Application Frameworks

Multimedia im Netz. Wintersemester 2011/12. Übung 10. Betreuer: Verantwortlicher Professor: Sebastian Löhmann. Prof. Dr.

Persistenz von Objekten relationale Datenbank Eigene Datenstruktur XML (JAXB) Proprietäre Dateiformate (Lochkarten)

Naviki GPS-Anwendungsentwicklung für Mobiltelefone

Dokumentieren mit Eclipse und Doxygen

JSP Grundlagen. JEE Vorlesung Teil 5. Ralf Gitzel

Beispiel: Methode mit einem Fehler. Diese Methode wird problematisch, wenn von außen eine Dauer von 0 Sekunden angegeben wird, etwa im Aufruf

Pragmatik von Programmiersprachen

Die Programmiersprache C99: Zusammenfassung

JOGGA Der Jogging-Companion

Software Engineering II

Datum, Uhrzeit: , Uhr Matrikelnummer:... Semester: INbac2 Prüfer: Prof. Meixner Note:...

Es wird das Struts <html:option> Element erläutert und anhand von kleinen Beispielen der Umgang veranschaulicht.

Transkript:

Machst Du noch Reflection oder annotierst Du schon? Bean-Mapping mit MapStruct Thomas Much thomas@muchsoft.com www.muchsoft.com 1

20 Jahre Java, 18 Jahre Beans JavaBeans JAXBEntities 2015 2006 2005 2000 1999 1998 JPAPOJOs Entities 1997 1995 Form Beans DTOs Typsicheres, schnelles BeanMapping! 2

Alte Architekturen 3

Was Java EE 5+ und JPA versprechen 4

Die moderne Realität 5

Das erforderliche Mapping @Entity @Table(name = "KUNDEN") public class Kunde { @Id Long id; long kundennummer; String name; @Enumerated KundenArt kundenart; public class KundeDTO { long id; String kundennummer; String name; String kundenart; Getter und Setter! Getter und Setter! 6

kann aufwendig werden DTO JPA- Entity REST- Entity JAXB- Entity View- Bean 7

Mapping-Implementation wie? Selbst programmiert alle Getter/Setter von Hand aufrufen eigene Reflection-Routinen Reflection-Bibliotheken: Apache BeanUtils http://commons.apache.org/proper/commons-beanutils/ Dozer http://dozer.sourceforge.net/ Probleme: Aufwand, Typunsicherheit, Performance 8

MapStruct MapStruct: http://mapstruct.org/ Annotations-Prozessor, der Mapping-Code generiert Keine Reflection! Typsicher und schnell Mind. Java 6, spezielle Unterstützung für Java 8 Minimale Laufzeitabhängigkeit (< 20 K) Je nach Komponentenmodell gar keine Abhängigkeit 9

Achtung, Beta! Seit 2013 in Entwicklung Aktuelle Version 1.0.0.Beta4 Finale Version bald erwartet http://de.wikipedia.org/wiki/entwicklungsstadium_(software)#beta-version 10

Artefakte (Dependencies) http://mvnrepository.com/artifact/org.mapstruct http://sourceforge.net/projects/mapstruct/files/ 11

Beispiel JPA-Entity nach DTO @Entity @Table(name = "KUNDEN") public class Kunde { @Id Long id; long kundennummer; String name; @Enumerated KundenArt kundenart; Alle public-properties sollen gemappt werden (auch aus Oberklassen) public class KundeDTO { long id; String kundennummer; String name; String kundenart; Getter und Setter! Getter und Setter! 12

Beispiel MapStruct minimal import org.mapstruct.mapper; import org.mapstruct.factory.mappers; @Mapper public interface KundeMapper { KundeMapper INSTANCE = Mappers.getMapper(KundeMapper.class); KundeDTO kunde2kundedto(kunde kunde); Live Demo KundeDTO dto = KundeMapper.INSTANCE.kunde2KundeDto( kunde ); 13

Beispiel generierter Code @Generated( value = "org.mapstruct.ap.mappingprocessor", date = "2015-04-21T22:01:21+0200", comments = "version: 1.0.0.Beta4, compiler: Eclipse JDT (IDE) " ) public class KundeMapperImpl implements KundeMapper { @Override public KundeDTO kunde2kundedto(kunde kunde) { if ( kunde == null ) { return null; date- und comments- Attribute können unterdrückt werden Mapper sind Thread-sicher! KundeDTO kundedto = new KundeDTO(); kundedto.setname( kunde.getname() ); kundedto.setkundennummer( String.valueOf( kunde.getkundennummer() ) ); if ( kunde.getkundenart()!= null ) { kundedto.setkundenart( kunde.getkundenart().tostring() ); if ( kunde.getid()!= null ) { kundedto.setid( kunde.getid() ); return kundedto; 14

Typsicherheit 15

Meldungen für Target-Properties Alternativ global per System-Property konfigurieren 16

Mapper in Komponentenmodellen default cdi spring jsr330 @Generated( value = "org.mapstruct.ap.mappingprocessor", ) @ApplicationScoped public class KundeMapperImpl implements KundeMapper { 17

Updates Beans ergänzen @Mapper public interface KundeMapper { Alternativ Target- Typ als Rückgabe (für fluent-aufrufe) void updatekundefromdto( KundeDTO kundedto, @MappingTarget Kunde kunde); Max. ein Mapping-Target 18

Objektgraphen mappen public class Kunde { Adresse adresse; public class KundeDTO { AdressDTO adresse; Getter und Setter! Getter und Setter! @Mapper public interface KundeMapper { KundeDTO kunde2kundedto(kunde kunde); AdresseDTO adresse2adressedto(adresse adresse); 19

Unterschiedliche Property-Namen @Mapper public interface KundeMapper { @Mappings({ @Mapping(source="id", target="entityid"), @Mapping(source="name", target="kundenname") ) KundeDTO kunde2kundedto(kunde kunde); @Mapping(source="plz", target="postleitzahl") AdresseDTO adresse2adressedto(adresse adresse); 20

Setter-Reihenfolge @Mapper public interface KundeMapper { @Mapping( target="kundennummer", dependson="kundenart") @Mapping( target="name", dependson={"vorname","nachname") KundeDTO kunde2kundedto(kunde kunde); setkundennummer() wird nach setkundenart() aufgerufen Keine zugesicherte Reihenfolge innerhalb des Arrays 21

Autom. (implizite) Typumwandlung Primitive Typen Wrapper (inkl. null-checks) int Integer etc. int/long/byte Integer etc. Primitive Typen & Wrapper String int/integer/boolean String etc. enum String BigInteger/BigDecimal Primitive/Wrapper/String 22

Autom. Typumwandlung (JAXB) JAXBElement<T> T List<JAXBElement<T>> List<T> XMLGregorianCalendar Date/Calendar 23

Autom. Typumwandlung (Datum+Zeit) Date/Calendar/XMLGregorianCalendar String / dateformat Joda String / dateformat Joda Date, Calendar java.time String / dateformat java.time Date, Calendar 24

Autom. Typumwandlung (Datum+Zeit) @Mapper public interface KundeMapper { @Mapping(source="geburtsdatum", dateformat="dd.mm.yyyy") KundeDTO kunde2kundedto(kunde kunde); @IterableMapping(dateFormat="dd.MM.yyyy") List<String> datelist2stringlist(list<date> list); 25

Mehrere Quell-Objekte Beans mixen @Mapper public interface KundeMapper { Bel. Verschachtelungstiefe (null-checks bei jedem Sprung) @Mappings({ @Mapping(target="empfaengerName", source="kunde.name"), @Mapping(target="postleitzahl", source="adresse.plz"), @Mapping(target="gewichtInKg", source="gewicht") ) Lieferanschrift buildlieferanschrift( Kunde kunde, Adresse adresse, Integer gewicht); Bel. viele Quell-Parameter 26

Arrays und Collections @Mapper public interface KundeMapper { CollectionMappingStrategy (Setter vs. Adder) konfigurierbar KundeDTO kunde2kundedto(kunde kunde); List<KundeDTO> kunden2dtos(list<kunde> kunden); KundeDTO[] kunden2dtos(kunde[] kunden); KundeDTO[] kundenlist2dtoarray(list<kunde> kunden); List<KundeDTO> kundenarray2dtolist(kunde[] kunden); Set<String> ints2strings(set<integer> ints); 27

Maps mappen @Mapper public interface KundeMapper { KundeDTO kunde2kundedto(kunde kunde); Ebenso keydateformat @MapMapping(valueDateFormat="dd.MM.yyyy") Map<String,String> mapknrdatum(map<long,date> map); 28

enum-werte abbilden @Mapper public interface KundeMapper { KundeDTO kunde2kundedto(kunde kunde); @Mapping(target="EXPRESS", source="premium") @Mapping(target="EXPRESS", source="aktion") @Mapping(target="STANDARD", source="normal") DtoKundenArt kundenart2dtokundenart(kundenart art); 29

Eigener Mapping-Code (1) @Mapper public abstract class KundeMapper { @Mappings({ ) public abstract KundeDTO kunde2kundedto(kunde k); public AdresseDTO adresse2adressedto(adresse adr) { eigener Mapping-Code 30

Eigener Mapping-Code (2) Eigene Mapping-Klasse muss dasselbe Komponentenmodell wie der MapStruct-Mapper verwenden! @Mapper(uses=AdresseMapper.class) public interface KundeMapper { @Mappings({ ) KundeDTO kunde2kundedto(kunde kunde); 31

Bean-Fabriken public class DtoFactory { public KundeDTO createkundedto() { return new KundeDTO(); public class EntityFactory { public <T extends BaseEntity> T createentity(@targettype Class<T> entityclass) { return entityclass.newinstance(); @Mapper(uses={DtoFactory.class, EntityFactory.class) public interface KundeMapper { KundeDTO kunde2kundedto(kunde kunde); Kunde kundedto2kunde(kundedto dto); 32

Exceptions beim Mapping public class SelbstgeschriebenerMapper { public KundenArt long2kundenart(long zahl) throws KundenArtException, SchwereException { Nicht deklarierte Checked-Exceptions werden als RuntimeExceptions weiter geworfen @Mapper(uses=SelbstgeschriebenerMapper.class) public interface KundeMapper { Kunde dto2kunde(kundedto dto) throws KundenArtException; 33

Konstante Werte im Ziel setzen @Mapper public interface KundeMapper { @Mapping( target="stringattribut", constant="mein String") @Mapping( target="intattribut", constant="23") @Mapping( target="longwrapperattribut", constant="12345678") @Mapping( target = "dateattribut", dateformat = "dd.mm.yyyy", constant = "24.04.2015" ) KundeDTO kunde2kundedto(kunde kunde); 34

Berechnete Werte im Ziel setzen @Mapper(imports=Date.class) public interface KundeMapper { @Mapping( target="geburtsdatum", expression= "java( new Date(kunde.getGeburtsdatumMillis()) )" ) KundeDTO kunde2kundedto(kunde kunde); 35

Methoden per Qualifier auswählen (1) public class AnredeMapper { public String deutsch2englisch(string anrede) { public String englisch2deutsch(string anrede) {? @Mapper(uses=AnredeMapper.class) public interface KundeMapper { KundeDTO kunde2kundedto(kunde kunde); 36

Methoden per Qualifier auswählen (2) @AnredeUebersetzer public class AnredeMapper { @DeutschNachEnglisch public String deutsch2englisch(string anrede) { @EnglischNachDeutsch public String englisch2deutsch(string anrede) { @Mapper public interface KundeMapper { @Mapping(target="anrede", qualifiedby={ Selbstgeschriebene @Qualifier-Annotationen AnredeUebersetzer.class,EnglischNachDeutsch.class ) KundeDTO kunde2kundedto(kunde kunde); 37

null-mapping anpassen Bei null-wert wird standardmäßig null gesetzt. Mit nullvaluemappingstrategy = NullValueMappingStrategy.RETURN_DEFAULT werden stattdessen Default-Werte gesetzt (für primitive Type, Listen etc.) Verfügbar bei @Mapper etc. 38

Mapping-Konfiguration "vererben" @Mapper public interface KundeMapper { @Mappings( ) KundeDTO kunde2kundedto(kunde kunde); @InheritConfiguration(name="kunde2KundeDto") @Mappings({ ) void updatedtofromkunde( Kunde kunde, @MappingTarget KundeDTO dto); 39

Umgekehrte Mappings @Mapper public interface KundeMapper { @Mappings( ) KundeDTO kunde2kundedto(kunde kunde); @InheritInverseConfiguration Kunde kundedto2kunde(kundedto dto); 40

Gemeinsam genutzte Konfigurationen @MapperConfig( mappinginheritancestrategy= MappingInheritanceStrategy.AUTO_INHERIT_FROM_CONFIG ) public class MeineKonfiguration { @Mappings({ ) BasisDTO entity2dto(basisentity entity); Hier wird noch kein Mapping-Code generiert! @Mapper(config=MeineKonfiguration.class) public interface KundeMapper { @Mappings({ ) KundeDTO kunde2kundedto(kunde kunde); 41

Ausblick Eclipse-Plugin https://github.com/mapstruct/mapstruct-eclipse/ Frühes Entwicklungsstadium 42

MapStruct Fazit Trotz Beta schon produktiv einsetzbar! Zur Not wird der generierte Code eingecheckt und später von Hand weiter gepflegt. Generierter Code ist einfach und lesbar. Flexible (Custom-)Mappings Einfache Einbindung in div. Komponentenmodelle 43

Fragen? Vielen Dank! thomas@muchsoft.com www.muchsoft.com www.javabarista.de 44