JavaRush /Блоги Java /Random-TG /Mapstruct чист ва чӣ гуна онро барои санҷиши воҳидҳо дар ...
Roman Beekeeper
Сатҳи

Mapstruct чист ва чӣ гуна онро барои санҷиши воҳидҳо дар замимаҳои SpringBoot дуруст танзим кардан мумкин аст

Дар гурӯҳ нашр шудааст

Замина

Салом ба ҳама, дӯстон ва хонандагони азизам! Пеш аз навиштани мақола, каме замина... Ман ба наздикӣ бо мушкor кор бо китобхонаи Mapstruct дучор шудам, ки онро дар канали телеграми худ дар ин ҷо ба таври мухтасар тавсиф кардам . Дар шарҳҳо, мушкилот бо пост ҳал карда шуд; ҳамкори ман аз лоиҳаи қаблӣ дар ин кор кӯмак кард. Mapstruct чист ва чӣ гуна онро барои санҷиши воҳидҳо дар замимаҳои SpringBoot дуруст танзим кардан мумкин аст.  Қисми 1 - 1Пас аз ин ман қарор додам, ки дар ин мавзӯъ мақолае нависам, аммо албатта мо назари танг нахоҳем дошт ва аввал кӯшиш мекунем, ки суръатро дарк кунем, Mapstruct чист ва чаро он лозим аст ва бо истифода аз як мисоли воқеӣ вазъияти пештар ба амал омадаро тахлил намуда, онро чй тавр хал кардан лозим аст. Аз ин рӯ, ман тавсия медиҳам, ки ҳама ҳисобҳоро дар баробари хондани мақола иҷро кунед, то ҳама чизро дар амал таҷриба кунед. Пеш аз он ки мо оғоз кунем, ба канали телеграми ман обуна шавед , ман фаъолиятҳои худро дар он ҷо ҷамъ мекунам, дар бораи рушд дар Java ва умуман IT фикрҳо менависам. Обуна шудед? Аҷоиб! Хуб, акнун меравем!

Mapstruct, савол?

Генератори рамз барои харитасозии лӯбиёи зуд барои навъи бехатар. Вазифаи аввалини мо фаҳмидани он аст, ки Mapstruct чист ва барои чӣ ба мо он лозим аст. Умуман, шумо метавонед дар ин бора дар вебсайти расмӣ хонед. Дар саҳифаи асосии сайт се ҷавоб ба саволҳо мавҷуд аст: он чист? Барои чӣ? Чӣ хел? Мо низ кӯшиш мекунем, ки ин корро кунем:

Ин чист?

Mapstruct китобхонаест, ки барои харита кардан (харита, умуман, он чизест, ки онҳо ҳамеша мегӯянд: харита, харита ва ғайра) an objectҳои баъзе an objectҳоро ба an objectҳои дигар an objectҳо бо истифода аз codeи тавлидшуда дар асоси конфигуратсияҳое, ки тавассути интерфейсҳо тавсиф мешаванд, кӯмак мекунад.

Барои чӣ?

Дар аксари мавридҳо, мо барномаҳои бисёрқабатаро таҳия мекунем (қабат барои кор бо пойгоҳи додаҳо, қабати мантиқи тиҷорӣ, қабат барои ҳамкории барнома бо ҷаҳони беруна) ва ҳар як қабат an objectҳои худро барои нигоҳдорӣ ва коркарди додаҳо дорад. . Ва ин маълумот бояд аз як қабат ба қабат тавассути интиқол аз як an object ба дигараш интиқол дода шавад. Барои онҳое, ки бо ин равиш кор накардаанд, ин метавонад каме мушкил ба назар расад. Масалан, мо барои пойгоҳи додаҳои донишҷӯён як an object дорем. Вақте ки маълумоти ин an object ба қабати мантиқи тиҷоратӣ (хидматҳо) меравад, мо бояд маълумотро аз синфи Student ба синфи StudentModel интиқол диҳем. Минбаъд, пас аз ҳама амалҳо бо мантиқи тиҷорат, маълумот бояд берун аз он озод карда шавад. Ва барои ин мо синфи StudentDto дорем. Албатта, мо бояд маълумотро аз синфи StudentModel ба StudentDto интиқол диҳем. Навиштани дастӣ ҳар дафъа усулҳои интиқолшаванда меҳнатталаб аст. Илова бар ин, ин рамзи иловагӣ дар пойгоҳи codeест, ки бояд нигоҳ дошта шавад. Шумо метавонед хато кунед. Ва Mapstruct чунин усулҳоро дар марҳилаи тартибдиҳӣ тавлид мекунад ва онҳоро дар манбаъҳои тавлидшуда нигоҳ медорад.

Чӣ хел?

Истифодаи эзоҳҳо. Мо танҳо бояд тавзеҳоте эҷод кунем, ки дорои annotationи асосии Mapper мебошад, ки ба китобхона мегӯяд, ки усулҳои ин интерфейсро барои тарҷума аз як an object ба an objectи дигар истифода бурдан мумкин аст. Тавре ки ман қаблан дар бораи донишҷӯён гуфта будам, дар ҳолати мо ин интерфейси StudentMapper хоҳад буд, ки дорои якчанд усулҳои интиқоли маълумот аз як қабат ба қабати дигар мебошад:
public class Student {
   private Long id;
   private String firstName;
   private String lastName;
   private Integer age;
}

public class StudentDTO {
   private Long id;
   private String firstName;
   private String lastName;
   private Integer age;
}

public class StudentModel {
   private Long id;
   private String firstName;
   private String lastName;
   private Integer age;
}
Барои ин синфҳо мо харитачӣ месозем (минбаъд ин интерфейс номида мешавад, ки он чизеро, ки мо мехоҳем ва ба куҷо интиқол диҳем, тавсиф мекунад):
@Mapper
public interface StudentMapper {
   StudentModel toModel(StudentDTO dto);
   Student toEntity(StudentModel model);
   StudentModel toModel(Student entity);
   StudentDTO toDto(StudentModel model);
}
Зебоии ин равиш дар он аст, ки агар номҳо ва намудҳои майдонҳо дар синфҳои гуногун якхела бошанд (чун дар ҳолати мо), танзимоти Mapstruct барои тавлиди амалисозии зарурӣ дар асоси интерфейси StudentMapper дар марҳилаи компиляция кифоя аст. тарҷума хоҳад кард. Пас, он аллакай равшантар шуд, дуруст? Биёед минбаъд равем ва барои таҳлor кор дар барномаи Spring Boot як мисоли воқеиро истифода барем.

Намунаи кори Spring Boot ва Mapstruct

Аввалин чизе, ки ба мо лозим аст, эҷод кардани лоиҳаи Spring Boot ва илова кардани Mapstruct ба он аст. Барои ин, ман дар GitHub як созмоне дорам , ки қолабҳо барои анборҳо доранд ва оғози Spring Boot яке аз онҳост. Дар асоси он, мо лоиҳаи нав эҷод мекунем: Баъдан, мо лоиҳароMapstruct чист ва чӣ гуна онро барои санҷиши воҳидҳо дар замимаҳои SpringBoot дуруст танзим кардан мумкин аст.  Қисми 1 - 2 мегирем . Бале, дӯстон, агар шумо онро муфид донед, ба лоиҳа ситора диҳед , пас ман медонам, ки ман ин корро беҳуда намекунам. Дар ин лоиҳа мо вазъиятеро ошкор хоҳем кард, ки ман дар ҷои кор гирифтаам ва дар як паём дар канали Telegram-и худ тавсиф кардаам . Ман вазъиятро барои онҳое, ки огоҳ нестанд, мухтасар шарҳ медиҳам: вақте ки мо барои харитасозон санҷишҳо менависем (яъне барои татбиқи интерфейсҳое, ки мо дар бораи он қаблан гуфта будем), мо мехоҳем, ки санҷишҳо ҳарчи зудтар гузаранд. Варианти соддатарин бо харитасозон ин истифодаи шарҳи SpringBootTest ҳангоми гузаронидани санҷиш мебошад, ки он тамоми ApplicationContext-и барномаи Spring Boot-ро мегирад ва харитасозеро, ки барои санҷиш дар дохor тест лозим аст, ворид мекунад. Аммо ин вариант ресурсталаб аст ва вақти бештарро мегирад, бинобар ин барои мо мувофиқ нест. Мо бояд санҷиши воҳидиро нависем, ки танҳо харитасози дилхоҳро эҷод кунад ва тафтиш кунад, ки усулҳои он маҳз ҳамон тавре ки мо интизор будем кор мекунанд. Чаро барои тезтар кор кардан ба шумо санҷишҳо лозиманд? Агар санҷишҳо муддати тӯлонӣ гиранд, он тамоми раванди рушдро суст мекунад. То он даме, ки санҷишҳо дар codeи нав гузаранд, ин codeро дуруст ҳисоб кардан мумкин нест ва барои озмоиш гирифта намешавад, яъне он ба истеҳсолот қабул карда намешавад ва ин маънои онро дорад, ки таҳиякунанда корро анҷом надодааст. Чунин ба назар мерасад, ки чаро барои китобхонае, ки фаъолияти он бешубҳа шубҳа дорад, санҷиш нависед? Ва аммо мо бояд санҷиш нависем, зеро мо месанҷем, ки чӣ тавр мо харитасозро дуруст тавсиф кардем ва оё он он чизеро, ки мо интизор будем, иҷро мекунад. Пеш аз ҳама, барои осон кардани кори мо, биёед Ломбокро ба лоиҳаи худ бо илова кардани вобастагии дигар ба pom.xml илова кунем:
<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <scope>provided</scope>
</dependency>
Дар лоиҳаи мо, мо бояд аз синфҳои намунавӣ (ки барои кор бо мантиқи тиҷорат истифода мешаванд) ба синфҳои DTO, ки мо барои иртибот бо ҷаҳони беруна истифода мебарем, гузарем. Дар versionи соддакардашудаи мо, мо тахмин мекунем, ки майдонҳо тағир намеёбанд ва харитасозони мо оддӣ хоҳанд буд. Аммо, агар хоҳиш вуҷуд дошта бошад, дар бораи чӣ гуна кор кардан бо Mapstruct, чӣ гуна танзим кардани он ва чӣ гуна бартариятҳои он истифода кардан мумкин аст, мақолаи муфассалтар навишта шавад. Аммо баъд, зеро ин мақола хеле дароз хоҳад буд. Фарз мекунем, ки мо студенте дорем, ки руйхати лекцияхо ва лекторонеро дорад, ки вай иштирок мекунад. Биёед бастаи намунавӣ эҷод кунем . Дар асоси ин, мо модели оддӣ эҷод мекунем:
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

import java.util.List;

@Data
public class StudentDTO {

   private Long id;

   private String name;

   private List<LectureDTO> lectures;

   private List<LecturerDTO> lecturers;
}
лекцияхои у
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

@Data
public class LectureDTO {

   private Long id;

   private String name;
}
ва лекторхо
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

@Data
public class LecturerDTO {

   private Long id;

   private String name;
}
Ва дар паҳлӯи бастаи намунавӣ бастаи dto эҷод кунед :
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

import java.util.List;

@Data
public class StudentDTO {

   private Long id;

   private String name;

   private List<LectureDTO> lectures;

   private List<LecturerDTO> lecturers;
}
лекцияхо
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

@Data
public class LectureDTO {

   private Long id;

   private String name;
}
ва лекторхо
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

@Data
public class LecturerDTO {

   private Long id;

   private String name;
}
Акнун биёед маппере созем, ки маҷмӯи моделҳои лексияро ба маҷмӯи лексияҳои DTO тарҷума кунад. Аввалин чизе, ки бояд кард, ба лоиҳа Mapstruct илова кардан аст. Барои ин, мо вебсайти онҳоро истифода хоҳем кард , ҳама чиз дар он ҷо тавсиф шудааст. Яъне, мо бояд як вобастагӣ ва плагинро ба хотираи худ илова кунем (агар шумо дар бораи чӣ будани хотира савол дошта бошед, ин ҷо равед, Моддаи 1 ва Моддаи 2 ):
<dependency>
   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct</artifactId>
   <version>1.4.2.Final</version>
</dependency>
ва дар хотира дар блоки <build/>. ки мо то ҳол надоштаем:
<build>
   <plugins>
       <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>3.5.1</version>
           <configuration>
               <source>1.8</source>
               <target>1.8</target>
               <annotationProcessorPaths>
                   <path>
                       <groupId>org.mapstruct</groupId>
                       <artifactId>mapstruct-processor</artifactId>
                       <version>1.4.2.Final</version>
                   </path>
               </annotationProcessorPaths>
           </configuration>
       </plugin>
   </plugins>
</build>
Минбаъд, биёед бастаи mapper дар паҳлӯи dto ва model эҷод кунем . Дар асоси синфҳое, ки мо қаблан нишон додем, ба шумо лозим меояд, ки боз панҷ харитасоз эҷод кунед:
  • Mapper LectureModel <-> LectureDTO
  • Рӯйхати харитасоз<LectureModel> <-> Рӯйхат<LectureDTO>
  • Маппер Лектор Модел <-> ЛекторДТО
  • Рӯйхати харитачӣ<LecturerModel> <-> Рӯйхат<ЛекторДТО>
  • Mapper StudentModel <-> StudentDTO
Бирав:

LectureMapper

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.dto.LecturerDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface LectureMapper {
   LectureDTO toDTO(LectureModel model);

   LectureModel toModel(LecturerDTO dto);
}

LectureListMapper

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.mapstruct.Mapper;

import java.util.List;

@Mapper(componentModel = "spring", uses = LectureMapper.class)
public interface LectureListMapper {
   List<LectureModel> toModelList(List<LectureDTO> dtos);
   List<LectureDTO> toDTOList(List<LectureModel> models);
}

Лектор Маппер

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface LectureMapper {
   LectureDTO toDTO(LectureModel model);

   LectureModel toModel(LectureDTO dto);
}

Лектор Рӯйхати харитачӣ

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LecturerDTO;
import com.github.romankh3.templaterepository.springboot.model.LecturerModel;
import org.mapstruct.Mapper;

import java.util.List;

@Mapper(componentModel = "spring", uses = LecturerMapper.class)
public interface LecturerListMapper {
   List<LecturerModel> toModelList(List<LecturerDTO> dloList);
   List<LecturerDTO> toDTOList(List<LecturerModel> modelList);
}

StudentMapper

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.StudentDTO;
import com.github.romankh3.templaterepository.springboot.model.StudentModel;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring", uses = {LectureListMapper.class, LecturerListMapper.class})
public interface StudentMapper {
   StudentDTO toDTO(StudentModel model);
   StudentModel toModel(StudentDTO dto);
}
Бояд алохида кайд кард, ки дар харитасозон мо ба дигар харитасозон мурочиат мекунем. Ин тавассути майдони истифода дар шарҳи Mapper анҷом дода мешавад, тавре ки дар StudentMapper анҷом дода мешавад:
@Mapper(componentModel = "spring", uses = {LectureListMapper.class, LecturerListMapper.class})
Дар ин чо барои дуруст тартиб додани руйхати лекцияхо ва руйхати лекторон ду мапператорро истифода мебарем. Акнун мо бояд codeи худро тартиб диҳем ва бубинем, ки дар он ҷо чӣ ва чӣ гуна аст. Инро бо истифода аз фармони mvn clean compile анҷом додан мумкин аст . Аммо, чунон ки маълум шуд, ҳангоми эҷоди татбиқи Mapstruct-и харитасозони мо, татбиқи харитасоз майдонҳоро аз нав нанавишт. Чаро? Маълум шуд, ки аз Ломбок гирифтани annotationи маълумот имконнопазир аст. Ва коре кардан лозим буд... Бинобар ин мо дар макола фас-ли нав дорем.

Пайваст кардани Lombok ва Mapstruct

Пас аз чанд дақиқаи ҷустуҷӯ маълум шуд, ки мо бояд Lombok ва Mapstruct-ро бо роҳи муайян пайваст кунем. Дар ин бора дар ҳуҷҷатҳои Mapstruct маълумот мавҷуд аст . Пас аз баррасии мисоли пешниҳодкардаи таҳиягарон аз Mapstruct, биёед pom.xml-и худро навсозӣ кунем: Биёед versionҳои алоҳида илова кунем:
​​<properties>
   <org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
   <lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>
Биёед вобастагии гумшударо илова кунем:
<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok-mapstruct-binding</artifactId>
   <version>${lombok-mapstruct-binding.version}</version>
</dependency>
Ва биёед плагини компилятори худро навсозӣ кунем, то он метавонад Lombok ва Mapstruct-ро пайваст кунад:
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-compiler-plugin</artifactId>
   <version>3.5.1</version>
   <configuration>
       <source>1.8</source>
       <target>1.8</target>
       <annotationProcessorPaths>
           <path>
               <groupId>org.mapstruct</groupId>
               <artifactId>mapstruct-processor</artifactId>
               <version>${org.mapstruct.version}</version>
           </path>
           <path>
               <groupId>org.projectlombok</groupId>
               <artifactId>lombok</artifactId>
               <version>${lombok.version}</version>
           </path>
           <path>
               <groupId>org.projectlombok</groupId>
               <artifactId>lombok-mapstruct-binding</artifactId>
               <version>${lombok-mapstruct-binding.version}</version>
           </path>
       </annotationProcessorPaths>
   </configuration>
</plugin>
Пас аз ин ҳама бояд кор кунад. Биёед лоиҳаи худро боз тартиб диҳем. Аммо синфҳоеро, ки Mapstruct тавлид кардааст, аз куҷо ёфтан мумкин аст? Онҳо дар сарчашмаҳои тавлидшуда ҳастанд: ${projectDir}/target/generated-sources/annotations/ Mapstruct чист ва чӣ гуна онро барои санҷиши воҳидҳо дар замимаҳои SpringBoot дуруст танзим кардан мумкин аст.  Қисми 1 - 3 Акнун, ки мо омодаем ноумедии маро аз пости Mapstruct дарк кунем, биёед кӯшиш кунем, ки барои харитасозон озмоишҳо эҷод кунем.

Мо барои харитасозони худ тестҳо менависем

Ман як санҷиши зуд ва оддӣ эҷод мекунам, ки яке аз харитасозонро дар ҳолате санҷида метавонад, ки мо санҷиши интегралӣ эҷод мекунем ва аз вақти анҷоми он хавотир нашавед:

LectureMapperTest

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class LectureMapperTest {

   @Autowired
   private LectureMapper mapperUnderTest;

   @Test
   void shouldProperlyMapModelToDto() {
       //given
       LectureModel model = new LectureModel();
       model.setId(11L);
       model.setName("lecture name");

       //when
       LectureDTO dto = mapperUnderTest.toDTO(model);

       //then
       Assertions.assertNotNull(dto);
       Assertions.assertEquals(model.getId(), dto.getId());
       Assertions.assertEquals(model.getName(), dto.getName());
   }

   @Test
   void shouldProperlyMapDtoToModel() {
       //given
       LectureDTO dto = new LectureDTO();
       dto.setId(11L);
       dto.setName("lecture name");

       //when
       LectureModel model = mapperUnderTest.toModel(dto);

       //then
       Assertions.assertNotNull(model);
       Assertions.assertEquals(dto.getId(), model.getId());
       Assertions.assertEquals(dto.getName(), model.getName());
   }
}
Дар ин ҷо, бо истифода аз шарҳи SpringBootTest, мо тамоми applicationContext-ро оғоз мекунем ва аз он бо истифода аз шарҳи Autowired синферо, ки барои санҷиш лозим аст, мебарорем. Аз нуқтаи назари суръат ва осонии навиштани тест, ин хеле хуб аст. Санҷиш бомуваффақият мегузарад, ҳама чиз хуб аст. Аммо мо бо роҳи дигар меравем ва барои харитасоз санҷиши воҳид менависем, масалан, LectureListMapper...
package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.List;

class LectureListMapperTest {

   private final LectureListMapper lectureListMapper = new LectureListMapperImpl();

   @Test
   void shouldProperlyMapListDtosToListModels() {
       //given
       LectureDTO dto = new LectureDTO();
       dto.setId(12L);
       dto.setName("I'm BATMAN!");

       List<LectureDTO> dtos = Collections.singletonList(dto);

       //when
       List<LectureModel> models = lectureListMapper.toModelList(dtos);

       //then
       Assertions.assertNotNull(models);
       Assertions.assertEquals(1, models.size());
       Assertions.assertEquals(dto.getId(), models.get(0).getId());
       Assertions.assertEquals(dto.getName(), models.get(0).getName());
   }
}
Азбаски татбиқҳое, ки Mapstruct тавлид мекунад, дар як синф бо лоиҳаи мо ҳастанд, мо метавонем онҳоро дар санҷишҳои худ ба осонӣ истифода барем. Ҳама чиз олиҷаноб ба назар мерасад - эзоҳ нест, мо синферо месозем, ки ба мо бо роҳи соддатарин лозим аст ва ҳамин тавр. Аммо вақте ки мо санҷишро иҷро мекунем, мо мефаҳмем, ки он вайрон мешавад ва дар консол NullPointerException вуҷуд хоҳад дошт... Ин аз он сабаб аст, ки татбиқи харитасози LectureListMapper чунин менамояд:
package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Generated(
   value = "org.mapstruct.ap.MappingProcessor",
   date = "2021-12-09T21:46:12+0300",
   comments = "version: 1.4.2.Final, compiler: javac, environment: Java 15.0.2 (N/A)"
)
@Component
public class LectureListMapperImpl implements LectureListMapper {

   @Autowired
   private LectureMapper lectureMapper;

   @Override
   public List<LectureModel> toModelList(List<LectureDTO> dtos) {
       if ( dtos == null ) {
           return null;
       }

       List<LectureModel> list = new ArrayList<LectureModel>( dtos.size() );
       for ( LectureDTO lectureDTO : dtos ) {
           list.add( lectureMapper.toModel( lectureDTO ) );
       }

       return list;
   }

   @Override
   public List<LectureDTO> toDTOList(List<LectureModel> models) {
       if ( models == null ) {
           return null;
       }

       List<LectureDTO> list = new ArrayList<LectureDTO>( models.size() );
       for ( LectureModel lectureModel : models ) {
           list.add( lectureMapper.toDTO( lectureModel ) );
       }

       return list;
   }
}
Агар мо ба NPE назар кунем (кӯтоҳ барои NullPointerException), мо онро аз тағирёбандаи lectureMapper мегирем , ки он оғоз нашудааст. Аммо дар татбиқи мо мо конструкторе надорем, ки бо он тағирёбандаро оғоз кунем. Маҳз аз ҳамин сабаб Mapstruct харитасозро ин тавр амалӣ кардааст! Дар фасли баҳор, шумо метавонед лӯбиёҳоро ба дарсҳо бо чанд роҳ илова кунед, шумо метавонед онҳоро тавассути майдон дар якҷоягӣ бо тавзеҳи Autowired, тавре ки дар боло анҷом дода шудааст, ворид кунед ё шумо метавонед онҳоро тавассути созанда ворид кунед. Ман худро дар чунин вазъияти мушкил дар ҷои кор пайдо кардам, вақте ки ба ман лозим буд, ки вақти иҷрои санҷишро оптимизатсия кунам. Гумон кардам, ки дар ин бора коре кардан мумкин нест ва дарди худро дар канали Телеграмам рехтам. Ва он гоҳ онҳо ба ман дар шарҳҳо кӯмак карданд ва гуфтанд, ки стратегияи тазриқро танзим кардан мумкин аст. Интерфейси Mapper дорои майдони injectionStrategy мебошад , ки танҳо номи InjectionStrategy -ро қабул мекунад , ки ду арзиш дорад: FIELD ва CONSTRUCTOR . Акнун, бо донистани ин, биёед ин танзимотро ба харитасозони худ илова кунем; Ман онро бо истифода аз LectureListMapper ҳамчун мисол нишон медиҳам :
@Mapper(componentModel = "spring", uses = LectureMapper.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface LectureListMapper {
   List<LectureModel> toModelList(List<LectureDTO> dtos);
   List<LectureDTO> toDTOList(List<LectureModel> models);
}
Ман қисми иловакардаамро бо ғафс таъкид кардам. Биёед ин хосиятро барои ҳамаи дигарон илова кунем ва лоиҳаро аз нав тартиб диҳем, то харитасозон бо хати нав тавлид шаванд. Пас аз анҷоми ин кор, биёед бубинем, ки татбиқи харитасоз барои LectureListMapper чӣ гуна тағир ёфтааст (қисмеро, ки ба мо лозим аст, бо ғафс нишон дода шудааст):
package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Generated(
   value = "org.mapstruct.ap.MappingProcessor",
   date = "2021-12-09T22:25:37+0300",
   comments = "version: 1.4.2.Final, compiler: javac, environment: Java 15.0.2 (N/A)"
)
@Component
public class LectureListMapperImpl implements LectureListMapper {

   private final LectureMapper lectureMapper;

   @Autowired
   public LectureListMapperImpl(LectureMapper lectureMapper) {

       this.lectureMapper = lectureMapper;
   }

   @Override
   public List<LectureModel> toModelList(List<LectureDTO> dtos) {
       if ( dtos == null ) {
           return null;
       }

       List<LectureModel> list = new ArrayList<LectureModel>( dtos.size() );
       for ( LectureDTO lectureDTO : dtos ) {
           list.add( lectureMapper.toModel( lectureDTO ) );
       }

       return list;
   }

   @Override
   public List<LectureDTO> toDTOList(List<LectureModel> models) {
       if ( models == null ) {
           return null;
       }

       List<LectureDTO> list = new ArrayList<LectureDTO>( models.size() );
       for ( LectureModel lectureModel : models ) {
           list.add( lectureMapper.toDTO( lectureModel ) );
       }

       return list;
   }
}
Ва ҳоло Mapstruct тазриқи mapper тавассути созандаро амалӣ кардааст. Ин маҳз он чизест, ки мо кӯшиш мекардем, ки ба даст орем. Акнун санҷиши мо тартиб доданро қатъ мекунад, биёед онро навсозӣ кунем ва ба даст орем:
package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.List;

class LectureListMapperTest {

   private final LectureListMapper lectureListMapper = new LectureListMapperImpl(new LectureMapperImpl());

   @Test
   void shouldProperlyMapListDtosToListModels() {
       //given
       LectureDTO dto = new LectureDTO();
       dto.setId(12L);
       dto.setName("I'm BATMAN!");

       List<LectureDTO> dtos = Collections.singletonList(dto);

       //when
       List<LectureModel> models = lectureListMapper.toModelList(dtos);

       //then
       Assertions.assertNotNull(models);
       Assertions.assertEquals(1, models.size());
       Assertions.assertEquals(dto.getId(), models.get(0).getId());
       Assertions.assertEquals(dto.getName(), models.get(0).getName());
   }
}
Ҳоло, агар мо санҷишро иҷро кунем, ҳама чиз тавре ки интизор мерафт, кор хоҳад кард, зеро дар LectureListMapperImpl мо LectureMapper-ро ба он ниёз дорем... Ғалаба! Ин барои шумо душвор нест, аммо ман хурсандам: Дӯстон, ҳама чиз маъмулӣ аст, ба ҳисоби GitHub , ба ҳисоби Telegram- и ман обуна шавед . Дар он ҷо ман натиҷаҳои фаъолияти худро ҷойгир мекунам, чизҳои воқеан муфид ҳастанд) Ман шуморо махсусан ба гурӯҳи мубоҳисавии канали телеграм даъват мекунам . Чунин мешавад, ки агар касе саволи техникӣ дошта бошад, дар он ҷо ҷавоб гирифта метавонад. Ин формат барои ҳама ҷолиб аст, шумо метавонед хонед, ки кӣ медонад ва таҷриба омӯзед.

Хулоса

Дар доираи ин мақола, мо бо чунин маҳсулоти зарурӣ ва зуд-зуд истифодашаванда ба монанди Mapstruct шинос шудем. Мо фаҳмидем, ки ин чист, чаро ва чӣ тавр. Бо истифода аз мисоли воқеӣ мо ҳис кардем, ки чӣ кор кардан мумкин аст ва чӣ гуна онро тағир додан мумкин аст. Мо инчунин ба он дидем, ки чӣ гуна сӯзандоруи лӯбиёро тавассути конструктор танзим кунем, то харитасозонро дуруст санҷидан мумкин бошад. Ҳамкасбон аз Mapstruct ба корбарони маҳсулоти худ имкон доданд, ки маҳз чӣ тавр ба харитасозон ворид карданро интихоб кунанд, ки мо бешубҳа ба онҳо миннатдорем. ВАЛЕ, сарфи назар аз он, ки Баҳор тавсия медиҳад, ки тавассути конструктор сӯзандоруи лӯбиёро пешниҳод кунад, бачаҳо аз Mapstruct ба таври нобаёнӣ сӯзандоруро тавассути майдон муқаррар кардаанд. Барои чӣ ин? Ҷавоб нест. Ман гумон мекунам, ки сабабҳое ҳастанд, ки мо намедонем ва барои ҳамин онҳо ин корро карданд. Ва барои фаҳмидани онҳо, ман дар анбори расмии маҳсулоти онҳо як GitHub эҷод кардам .
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION