Gyűjtemények leképezése a MapStruct segítségével

1. Áttekintés

Ebben az oktatóanyagban megvizsgáljuk, hogyan lehet térképezni az objektumok gyűjteményeit a MapStruct segítségével.

Mivel ez a cikk már feltételezi a MapStruct alapvető ismereteit, a kezdőknek először meg kell nézniük a MapStruct gyors útmutatót.

2. Gyűjtemények feltérképezése

Általánosságban, a gyűjtemények leképezése a MapStruct segítségével ugyanúgy működik, mint az egyszerű típusoknál.

Alapvetően létre kell hoznunk egy egyszerű felületet vagy absztrakt osztályt, és deklarálnunk kell a leképezési módszereket. Nyilatkozataink alapján a MapStruct automatikusan elkészíti a leképezési kódot. Általában a létrehozott kód végiggurul a forrásgyűjteményen, minden elemet átalakít céltípussá, és mindegyiket felveszi a célgyűjteménybe.

Vessünk egy pillantást egy egyszerű példára.

2.1. Listák leképezése

Először nézzük meg egy egyszerű POJO-t térképkészítőnk feltérképezési forrásaként:

public class Alkalmazott {private String keresztnév; privát karakterlánc vezetéknév; // kivitelező, mérőeszközök és beállítók} 

A cél egy egyszerű DTO lesz:

public class EmployeeDTO {private String keresztnév; privát karakterlánc vezetéknév; // szerelők és beállítók}

Ezután határozzuk meg a térképkészítőnket:

@Mapper nyilvános felület EmployeeMapper {Lista térkép (Lista alkalmazottak); } 

Végül nézzük meg a mi általunk generált MapStruct kódot EmployeeMapper felület:

public class EmployeeMapperImpl implementálja az EmployeeMapper {@Override public List map (List alkalmazottak) {if (alkalmazottak == null) {return null; } Lista lista = new ArrayList (alkalmazottak.méret ()); for (Munkavállalói alkalmazott: alkalmazottak) {list.add (workerToEmployeeDTO (alkalmazott)); } visszatérési lista; } védett EmployeeDTO workerToEmployeeDTO (alkalmazott alkalmazott) {if (alkalmazott == null) {return null; } EmployeeDTO alkalmazottDTO = new EmployeeDTO (); alkalmazottDTO.setFirstName (alkalmazott.getFirstName ()); workerDTO.setLastName (alkalmazott.getLastName ()); visszatérő alkalmazottDTO; }} 

Fontos megjegyezni. Kimondottan, A MapStruct automatikusan generálta nekünk a leképezést Munkavállaló nak nek AlkalmazottDTO.

Vannak esetek, amikor ez nem lehetséges. Tegyük fel például, hogy feltérképezni akarjuk a sajátjainkat Munkavállaló modellt a következő modellhez:

public class EmployeeFullNameDTO {private String fullName; // getter és setter}

Ebben az esetben, ha csak az a-ból deklaráljuk a leképezési módszert Lista nak,-nek Munkavállaló a Lista nak,-nek EmployeeFullNameDTO fordítási idejű hibát vagy figyelmeztetést kapunk, például:

Figyelmeztetés: (11, 31) java: Nem hozzárendelt céltulajdonság: "fullName". Hozzárendelés a "com.baeldung.mapstruct.mappingCollections.model.Employee alkalmazott" gyűjteményi elemről a "com.baeldung.mapstruct.mappingCollections.dto.EmployeeFullNameDTO workerFullNameDTO" elemre.

Alapvetően ez azt jelenti A MapStruct nem tudta automatikusan generálni a leképezést számunkraebben az esetben. Ezért manuálisan meg kell határoznunk a leképezést Munkavállaló és EmployeeFullNameDTO.

Ezen pontok alapján határozzuk meg manuálisan:

@Mapper nyilvános felület EmployeeFullNameMapper {Lista térkép (Lista alkalmazottak); alapértelmezett EmployeeFullNameDTO térkép (alkalmazott alkalmazott) {EmployeeFullNameDTO alkalmazottInfoDTO = új EmployeeFullNameDTO (); workerInfoDTO.setFullName (alkalmazott.getFirstName () + "" + alkalmazott.getLastName ()); visszatérő alkalmazottInfoDTO; }}

A generált kód az általunk meghatározott módszert használja a forrás elemeinek feltérképezéséhez Lista a cél felé Lista.

Ez általánosságban is érvényes. Ha meghatároztunk egy módszert, amely a forráselem-típust a célelemtípushoz társítja, akkor a MapStruct fogja használni.

2.2. Készletek és térképek leképezése

A MapStruct segítségével a térképkészletek ugyanúgy működnek, mint a listákkal. Tegyük fel például, hogy feltérképezni szeretnénk a Készlet nak,-nek Munkavállaló példányok a Készlet nak,-nek AlkalmazottDTO példányok.

Mint korábban, szükségünk van egy térképezőre:

@Mapper nyilvános felület EmployeeMapper {Térkép beállítása (Alkalmazottak beállítása); }

A MapStruct pedig létrehozza a megfelelő kódot:

public class EmployeeMapperImpl implementálja az EmployeeMapper {@Override public Set map (Set alkalmazottak) {if (alkalmazottak == null) {return null; } Set set = new HashSet (Math.max ((int) (alkalmazottak.méret () / .75f) + 1, 16)); for (Alkalmazott alkalmazott: alkalmazottak) {set.add (workerToEmployeeDTO (alkalmazott)); } visszatérési készlet; } védett EmployeeDTO workerToEmployeeDTO (alkalmazott alkalmazott) {if (alkalmazott == null) {return null; } EmployeeDTO alkalmazottDTO = new EmployeeDTO (); alkalmazottDTO.setFirstName (alkalmazott.getFirstName ()); workerDTO.setLastName (alkalmazott.getLastName ()); visszatérő alkalmazottDTO; }}

Ugyanez vonatkozik a térképekre is. Vegyük fontolóra, hogy szeretnénk feltérképezni a Térkép a Térkép.

Ezután ugyanazokat a lépéseket hajthatjuk végre, mint korábban:

@Mapper nyilvános felület EmployeeMapper {Térképtérkép (Map idEmployeeMap); }

A MapStruct pedig elvégzi a dolgát:

public class EmployeeMapperImpl megvalósítja az EmployeeMapper {@Override public Map map (Map idEmployeeMap) {if (idEmployeeMap == null) {return null; } Térképtérkép = új HashMap (Math.max ((int) (idEmployeeMap.size () / .75f) + 1, 16)); for (java.util.Map.Entry bejegyzés: idEmployeeMap.entrySet ()) {String kulcs = entry.getKey (); EmployeeDTO érték = workerToEmployeeDTO (bejegyzés.getValue ()); map.put (kulcs, érték); } visszatérési térkép; } védett EmployeeDTO workerToEmployeeDTO (alkalmazott alkalmazott) {if (alkalmazott == null) {return null; } EmployeeDTO alkalmazottDTO = new EmployeeDTO (); alkalmazottDTO.setFirstName (alkalmazott.getFirstName ()); workerDTO.setLastName (alkalmazott.getLastName ()); visszatérő alkalmazottDTO; }}

3. Gyűjtemény-feltérképezési stratégiák

Gyakran fel kell térképeznünk a szülő-gyermek viszonnyal rendelkező adattípusokat. Jellemzően van egy adattípus (szülő), amelynek a mezője Gyűjtemény más adattípus (gyermek).

Ilyen esetekben A MapStruct lehetőséget kínál arra, hogy kiválassza, hogyan állítsa be vagy adja hozzá a gyerekeket a szülőtípushoz. Különösen a @Mapper az annotációnak van egy collectionMappingStrategy attribútum, amely lehet CSAK KIEGÉSZÍTŐ, SETTER_PREFERRED, ADDER_PREFERRED vagy TARGET_IMMUTABLE.

Ezek az értékek arra utalnak, hogy a gyerekeket hogyan kell beállítani vagy hozzáadni a szülőtípushoz. Az alapértelmezett érték: CSAK KIEGÉSZÍTŐK, ami azt jelenti, hogy csak hozzáférőket lehet használni a Gyűjtemény gyerekekből.

Ez az opció jól jön, ha a beállítója a Gyűjtemény mező nem érhető el, de van egy összeadónk. Egy másik eset, amelyben ez hasznos, az amikor az Gyűjtemény megváltoztathatatlan a szülőtípuson. Általában generált céltípusokban találkozunk ezekkel az esetekkel.

3.1. CSAK KIEGÉSZÍTŐ Gyűjtemény-feltérképezési stratégia

Vegyünk egy példát, hogy jobban megértsük ennek működését.

Példaként hozzunk létre egy Vállalat osztály mint feltérképezési forrásunk:

public class Társaság {private List alkalmazottak; // getter és setter}

A térképezésünk célja pedig egy egyszerű DTO lesz:

public class CompanyDTO {private List alkalmazottak; public list getEmployees () {visszatérő alkalmazottak; } public void setEmployees (List alkalmazottak) {this.employees = alkalmazottak; } public void addEmployee (EmployeeDTO workerDTO) {if (alkalmazottak == null) {alkalmazottak = new ArrayList (); } alkalmazottak.add (alkalmazottDTO); }}

Ne feledje, hogy mindkettőnknek van beállítója, setEmployees, és az összeadó, addEmployee, elérhető. Is, a kiegészítésért mi felelünk a gyűjtemény inicializálásáért.

Tegyük fel, hogy feltérképezni szeretnénk a Vállalat a CompanyDTO. Ezután, mint korábban, térképkészítőre van szükségünk:

@Mapper (uses = EmployeeMapper.class) nyilvános felület CompanyMapper {CompanyDTO térkép (Company company); }

Ne feledje, hogy a EmployeeMapper és az alapértelmezett collectionMappingStrategy.

Most nézzük meg a MapStruct által létrehozott kódot:

public class CompanyMapperImpl implementálja a CompanyMapper {private final EmployeeMapper workerMapper = Mappers.getMapper (EmployeeMapper.class); @Orride public CompanyDTO map (Company company) {if (vállalat == null) {return null; } CompanyDTO companyDTO = new CompanyDTO (); companyDTO.setEmployees (alkalmazottMapper.map (vállalat.getEmployees ())); visszatérő társaságDTO; }}

Ahogy látható, A MapStruct a beállítót használja, setEmployees, a Lista nak,-nek AlkalmazottDTO példányok. Ez azért történik, mert itt az alapértelmezettet használjuk collectionMappingStrategy,CSAK KIEGÉSZÍTŐ.

A MapStruct talált egy metódust a Lista a Lista ban ben EmployeeMapper és újra felhasználta.

3.2. ADDER_PREFERRED Gyűjtemény-feltérképezési stratégia

Ezzel szemben vegyük figyelembe, hogy használtunk ADDER_PREFERRED mint collectionMappingStrategy:

@Mapper (collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, uses = EmployeeMapper.class) nyilvános felület CompanyMapperAdderPreferred {CompanyDTO térkép (Vállalat); }

Ismét szeretnénk újrafelhasználni a EmployeeMapper. Azonban, kifejezetten hozzá kell adnunk egy módszert, amely képes átalakítani az egyeseket Munkavállaló egy AlkalmazottDTO első:

@Mapper nyilvános felület EmployeeMapper {EmployeeDTO térkép (Alkalmazott alkalmazott); Listatérkép (List alkalmazottak); Térkép beállítása (Alkalmazottak beállítása); Térképtérkép (Map idEmployeeMap); }

A MapStruct ugyanis a hozzáadót használja a hozzáadókhoz AlkalmazottDTO példányok a célig CompanyDTO példány egyenként:

public class CompanyMapperAdderPreferredImpl implementálja a CompanyMapperAdderPreferred {private final EmployeeMapper workerMapper = Mappers.getMapper (EmployeeMapper.class); @Orride public CompanyDTO map (Company company) {if (vállalat == null) {return null; } CompanyDTO companyDTO = new CompanyDTO (); if (cég.getEmployees ()! = null) {for (Munkavállalói alkalmazott: cég.getEmployees ()) {cégDTO.addEmployee (alkalmazottMapper.map (alkalmazott)); }} return companyDTO; }}

Abban az esetben, ha a kiegészítő nem áll rendelkezésre, a beállítót használták volna.

A MapStruct referencia dokumentációjában megtalálhatjuk az összes gyűjtemény-feltérképezési stratégia teljes leírását.

4. A célgyűjtés megvalósítási típusai

A MapStruct a gyűjteményfelületeket a térképezési módszerek céltípusaként támogatja.

Ebben az esetben a létrehozott kódban néhány alapértelmezett megvalósítást használnak. Például a Lista van Tömb lista amint az a fenti példáinkból megállapítható.

A MapStruct által támogatott felületek és azok alapértelmezett megvalósításainak teljes listáját a referencia dokumentációban találjuk meg.

5. Következtetés

Ebben a cikkben azt kutattuk, hogyan lehet térképeket gyűjteni a MapStruct segítségével.

Először megvizsgáltuk, hogyan tudnánk feltérképezni a különböző típusú gyűjteményeket. Aztán megláttuk, hogyan testreszabhatjuk a szülő-gyermek kapcsolattérképeket a gyűjtemény-feltérképezési stratégiák segítségével.

Útközben kiemeltük azokat a legfontosabb szempontokat és dolgokat, amelyeket szem előtt kell tartani a MapStruct használatával történő gyűjtemények feltérképezése során.

Szokás szerint a teljes kód elérhető a GitHubon.