Баршаңызға сәлем, құрметті достарым және оқырмандарым! Мақаланы жазбас бұрын, қысқаша мәлімет... Жақында мен Mapstruct кітапханасымен жұмыс істеу мәселесіне тап болдым, ол туралы телеграм каналымда қысқаша сипаттадым . Түсініктемелерде постқа қатысты мәселе шешілді, бұған алдыңғы жобадағы әріптесім көмектесті. Осыдан кейін мен осы тақырып бойынша мақала жазуды шештім, бірақ біз, әрине, тар көзқарасты қабылдамаймыз және алдымен жылдамдыққа жетуге тырысамыз, Mapstruct деген не және ол не үшін қажет екенін түсінеміз және нақты мысалды қолданамыз. бұрын туындаған жағдайды және оны шешу жолдарын талдау. Сондықтан, мен бәрін тәжірибеде сезіну үшін мақаланы оқумен қатар барлық есептеулерді орындауды ұсынамын. Бастамас бұрын, менің телеграм каналыма жазылыңыз , мен онда өз әрекеттерімді жинаймын, Java және жалпы IT-дағы даму туралы ойлар жазамын. Жазылдыңыз ба? Тамаша! Ал, енді кеттік!
Mapstruct, жиі қойылатын сұрақтар?
Жылдам типті қауіпсіз бұршақ салыстыруларына арналған code генераторы. Біздің бірінші міндетіміз Mapstruct деген не екенін және оның бізге не үшін қажет екенін анықтау. Жалпы, бұл туралы ресми сайттан оқуға болады. Сайттың негізгі бетінде сұрақтарға үш жауап бар: бұл не? Не үшін? Қалай? Біз мұны да жасауға тырысамыз:
Бұл не?
Mapstruct — интерфейстер арқылы сипатталған конфигурациялар негізінде жасалған codeты пайдалана отырып, кейбір нысандардың нысандарын басқа нысандардың an objectілеріне салыстыруға (карта, жалпы алғанда, олар әрқашан осылай дейді: карта, карта және т.б.) көмектесетін кітапхана.
Не үшін?
Көбінесе біз көп деңгейлі қосымшаларды әзірлейміз (деректер қорымен жұмыс істеу қабаты, бизнес-логика қабаты, қолданбаның сыртқы әлеммен әрекеттесу қабаты) және әрбір қабатта деректерді сақтауға және өңдеуге арналған өз нысандары бар. . Және бұл деректерді бір нысаннан екіншісіне тасымалдау арқылы қабаттан қабатқа тасымалдау қажет. Бұл тәсілмен жұмыс істемегендер үшін бұл біршама күрделі болып көрінуі мүмкін. Мысалы, бізде Студенттік дерекқорға арналған нысан бар. Бұл нысанның деректері бизнес логикасы (қызметтері) деңгейіне өткенде, біз Студент сыныбынан StudentModel сыныбына деректерді тасымалдауымыз керек. Әрі қарай, бизнес логикасы бар барлық манипуляциялардан кейін деректерді сыртқа шығару керек. Бұл үшін бізде StudentDto сыныбы бар. Әрине, біз StudentModel сыныбынан StudentDto-ға деректерді беруіміз керек. Ауыстырылатын әдістерді қолмен жазу көп еңбекті қажет етеді. Оған қоса, бұл code базасында сақталуы қажет қосымша code. Сіз қате жібере аласыз. Mapstruct мұндай әдістерді компиляция сатысында жасайды және оларды жасалған көздерде сақтайды.
Қалай?
Аннотацияларды пайдалану. Бізге кітапханаға осы интерфейстегі әдістерді бір нысаннан екіншісіне аудару үшін пайдалануға болатынын айтатын негізгі Mapper annotationсы бар annotation жасау керек. Студенттер туралы бұрын айтқанымдай, біздің жағдайда бұл StudentMapper интерфейсі болады, онда деректерді бір қабаттан екінші қабатқа тасымалдаудың бірнеше әдістері болады:
Бұл тәсілдің сұлулығы мынада, егер өрістердің атаулары мен түрлері әртүрлі класстарда бірдей болса (біздің жағдайымыздағыдай), онда Mapstruct параметрлері компиляция сатысында StudentMapper интерфейсі негізінде қажетті іске асыруды генерациялау үшін жеткілікті, ол аударатын болады. Демек, бұл түсінікті болды, солай ма? Әрі қарай барып, Spring Boot қолданбасындағы жұмысты талдау үшін нақты мысалды қолданайық.
Spring Boot және Mapstruct жұмысының мысалы
Бізге қажет бірінші нәрсе - Spring Boot жобасын жасау және оған Mapstruct қосу. Бұл мәселе бойынша менде GitHub-та репозиторийлерге арналған үлгілері бар ұйым бар және Spring Boot бастауы солардың бірі болып табылады. Оның негізінде біз жаңа жобаны жасаймыз: Келесі, біз жобаны аламыз . Иә, достар, жобаны пайдалы деп тапсаңыз, жұлдызша беріңіз , сондықтан мен мұны бекер жасап жатқан жоқпын. Бұл жобада біз жұмыста алған және Telegram арнамдағы постта сипатталған жағдайды ашамыз . Мен білмейтіндер үшін жағдайды қысқаша сипаттаймын: біз карта жасаушыларға арналған сынақтарды жазғанда (яғни, біз бұрын айтқан интерфейсті іске асыру үшін) сынақтардың мүмкіндігінше тез өткенін қалаймыз. Маперлермен ең қарапайым опция сынақты іске қосу кезінде SpringBootTest annotationсын пайдалану болып табылады, ол Spring Boot қолданбасының барлық ApplicationContext мәтінін таңдайды және сынақ ішінде сынақ үшін қажетті салыстырғышты енгізеді. Бірақ бұл опция ресурсты қажет етеді және әлдеқайда көп уақытты алады, сондықтан ол бізге жарамайды. Біз жай ғана қажетті карта жасаушыны жасайтын және оның әдістері біз күткендей жұмыс істейтінін тексеретін бірлік сынамасын жазуымыз керек. Неліктен жылдамырақ жұмыс істеу үшін сынақтар қажет? Егер сынақтар ұзақ уақытқа созылса, ол бүкіл даму процесін баяулатады. Тесттер жаңа codeты бермейінше, бұл codeты дұрыс деп санауға болмайды және тестілеуге қабылданбайды, яғни ол өндіріске қабылданбайды және әзірлеуші жұмысты аяқтамағанын білдіреді. Жұмысы күмән тудырмайтын кітапханаға тест жазудың қажеті қанша? Дегенмен, біз тест жазуымыз керек, өйткені біз карта жасаушыны қаншалықты дұрыс сипаттағанымызды және оның біз күткенді орындайтынын тексереміз. Ең алдымен, жұмысымызды жеңілдету үшін pom.xml файлына басқа тәуелділікті қосу арқылы жобамызға Lombok қосамыз:
Біздің жобамызда біз модельдік сыныптардан (бизнес логикасымен жұмыс істеу үшін пайдаланылады) сыртқы әлеммен байланысу үшін қолданатын DTO сыныптарына көшуіміз керек. Жеңілдетілген нұсқамызда өрістер өзгермейді және біздің карта жасаушылар қарапайым болады деп есептейміз. Бірақ, егер тілек болса, Mapstruct-пен қалай жұмыс істеу керек, оны қалай конфигурациялау керек және оның артықшылықтарын қалай пайдалану керектігі туралы толығырақ мақала жазуға болады. Бірақ содан кейін, өйткені бұл мақала өте ұзақ болады. Бізде ол қатысатын дәрістер мен лекторлардың тізімі бар студент бар делік. Үлгі пакетін жасайық . Осыған сүйене отырып, біз қарапайым модель жасаймыз:
Енді лекция үлгілерінің жинағын DTO лекцияларының жинағына аударатын карта жасаушыны жасайық. Ең алдымен жобаға Mapstruct қосу керек. Мұны істеу үшін біз олардың ресми сайтын қолданамыз , бәрі сонда сипатталған. Яғни, біз жадымызға бір тәуелділік пен плагинді қосуымыз керек (егер жад деген не туралы сұрақтарыңыз болса, 1-бап және 2-бап ):
Мапперлерде біз басқа бейнелеушілерге сілтеме жасайтынымызды бөлек атап өту керек. Бұл StudentMapper қолданбасында орындалғандай, Mapper annotationсындағы uses өрісі арқылы орындалады:
Мұнда лекциялар тізімі мен лекторлар тізімін дұрыс картаға түсіру үшін екі мапперді қолданамыз. Енді біз codeты құрастырып, не және қалай бар екенін көруіміз керек. Мұны mvn clean compile командасы арқылы жасауға болады . Бірақ, белгілі болғандай, біздің карта жасаушылардың Mapstruct іске асыруларын жасаған кезде, картаның іске асырулары өрістерді қайта жазбаған. Неліктен? Ломбоктан Data annotationсын алу мүмкін емес екені белгілі болды. Және бірдеңе істеу керек еді... Сондықтан мақалада жаңа бөлім бар.
Lombok және Mapstruct байланыстыру
Бірнеше minutesтық іздеулерден кейін бізге Lombok пен Mapstruct-ті белгілі бір жолмен қосу керек болды. Бұл туралы ақпарат Mapstruct құжаттамасында бар . Mapstruct әзірлеушілері ұсынған мысалды зерттегеннен кейін, pom.xml файлын жаңартайық: Бөлек нұсқаларды қосамыз:
Осыдан кейін бәрі ойдағыдай болуы керек. Жобамызды қайтадан құрастырайық. Бірақ Mapstruct жасаған сыныптарды қайдан табуға болады? Олар генерацияланған көздерде: ${projectDir}/target/generated-sources/annotations/ Mapstruct жазбасынан көңілі қалғанымды түсінуге дайынбыз, енді карта жасаушылар үшін сынақтар жасап көрейік.
Біз карта жасаушыларымызға тест жазамыз
Мен интеграциялық тест жасап жатқан жағдайда карта жасаушылардың бірін сынайтын жылдам және қарапайым сынақ жасаймын және оның аяқталу уақыты туралы алаңдамаңыз:
Мұнда SpringBootTest annotationсын қолдана отырып, біз бүкіл applicationContext бағдарламасын іске қосамыз және одан Autowired annotationсын пайдаланып, тестілеуге қажетті классты шығарамыз. Тест жазудың жылдамдығы мен жеңілдігі тұрғысынан бұл өте жақсы. Сынақ сәтті өтті, бәрі жақсы. Бірақ біз басқа жолмен жүреміз және карта жасаушы үшін бірлік сынағын жазамыз, мысалы, LectureListMapper...
Mapstruct жасайтын іске асырулар жобамызбен бір сыныпта болғандықтан, біз оларды сынақтарымызда оңай пайдалана аламыз. Барлығы керемет көрінеді - annotationлар жоқ, біз ең қарапайым түрде қажет классты жасаймыз және солай. Бірақ сынақты орындаған кезде біз оның бұзылатынын және консольде NullPointerException болатынын түсінеміз... Себебі LectureListMapper салыстырушысының іске асырылуы келесідей көрінеді:
Егер NPE (NullPointerException сөзінің қысқасы) қарасақ, біз оны lectureMapper айнымалысынан аламыз , ол инициализацияланбаған болып шығады. Бірақ біздің іске асыруда бізде айнымалыны инициализациялай алатын конструктор жоқ. Mapstruct карта жасаушыны осылай іске асырғанының себебі осы! Көктемде сабақтарға бұршақтарды бірнеше жолмен қосуға болады, оларды жоғарыда орындалғандай Autowired annotationсымен бірге өріс арқылы енгізуге болады немесе конструктор арқылы енгізуге болады. Тестті орындау уақытын оңтайландыру қажет болғанда мен жұмыста осындай проблемалық жағдайға тап болдым. Мен мұнымен ештеңе істей алмаймын деп ойлап, Telegram каналыма мұңымды төгіп тастадым. Содан кейін олар маған түсініктемелерде көмектесті және инъекция стратегиясын теңшеуге болатынын айтты. Mapper интерфейсінде екі мәні бар InjectionStrategy атауын қабылдайтын injectionStrategy өрісі бар: FIELD және CONSTRUCTOR . Енді, мұны біле отырып, бұл параметрді карташыларға қосамыз; мен оны мысал ретінде LectureListMapper арқылы көрсетемін :
Мен қосылған бөлікті қою қаріппен белгіледім. Осы опцияны барлық қалғандары үшін қосып, жобаны қайта құрастырайық, осылайша карта жасаушылар жаңа жолмен жасалады. Бұл әрекетті орындағаннан кейін, LectureListMapper үшін картаны іске асырудың қалай өзгергенін көрейік (бізге қажет бөлік қою қаріппен белгіленген):
Енді Mapstruct конструктор арқылы маппер инъекциясын жүзеге асырды. Біз дәл осы мақсатқа жетуге тырыстық. Енді біздің тест құрастыруды тоқтатады, оны жаңартып, алайық:
Енді тестті орындасақ, бәрі күткендей жұмыс істейді, өйткені LectureListMapperImpl бағдарламасында біз оған қажет LectureMapper тапсырамыз... Жеңіс! Бұл сізге қиын емес, бірақ мен ризамын: Достар, бәрі әдеттегідей, менің GitHub аккаунтыма , Telegram аккаунтыма жазылыңыз . Онда мен өз іс-әрекеттерімнің нәтижелерін жариялаймын, шынымен де пайдалы нәрселер бар) Мен сізді әсіресе телеграм каналының пікірталас тобына қосылуға шақырамын . Егер біреудің техникалық сұрағы болса, сол жерден жауап ала алатындай болады. Бұл формат барлығына қызық, кім не білетінін оқып, тәжірибе жинақтай аласыз.
Қорытынды
Осы мақаланың аясында біз Mapstruct сияқты қажетті және жиі қолданылатын өніммен таныстық. Біз оның не екенін, неге және қалай екенін анықтадық. Нақты мысалды қолдана отырып, біз не істеуге болатынын және оны қалай өзгертуге болатынын сезіндік. Біз сондай-ақ конструктор арқылы бұршақты инъекциялауды қалай орнату керектігін қарастырдық, осылайша карта жасаушыларды дұрыс сынауға болады. Mapstruct әріптестері өз өнімін пайдаланушыларға карта жасаушыларды қалай енгізу керектігін таңдауға мүмкіндік берді, бұл үшін біз оларға алғысымыз шексіз. БІРАҚ, Spring конструктор арқылы бұршақтарды инъекциялауды ұсынғанына қарамастан, Mapstruct жігіттері әдепкі бойынша өріс арқылы инъекцияны орнатқан. Неге бұлай? Жауап жоқ. Менің ойымша, біз білмейтін себептер болуы мүмкін, сондықтан олар осылай жасады. Олардан білу үшін мен олардың ресми өнім репозиторийінде GitHub мәселесін жасадым.
GO TO FULL VERSION