Баарыңарга салам, кымбаттуу досторум жана окурмандарым! Макаланы жазуудан мурун, бир аз маалымат... Мен жакында эле Mapstruct китепканасы менен иштөөдө көйгөйгө туш болдум, бул жерде мен телеграм каналымда кыскача сүрөттөп бердим . Комментарийлерде посттун көйгөйү чечилди, буга мурунку долбоордогу кесиптешим жардам берди. Ошондон кийин мен бул тема боюнча макала жазууну чечтим, бирок, албетте, биз тар көз карашты карманбайбыз жана алгач тездик менен иштөөгө, Mapstruct деген эмне экенин жана ал эмне үчүн керек экенин түшүнүүгө аракет кылабыз жана чыныгы мисалды колдонуп, мурда пайда болгон кырдаалды жана аны чечүүнүн жолдорун талдоо. Ошондуктан, мен бардыгын иш жүзүндө көрүү үчүн макаланы окуу менен катар бардык эсептөөлөрдү жасоону сунуш кылам. Баштоодон мурун, менин телеграм каналыма жазылыңыз , мен ал жерде өзүмдүн иш-аракеттеримди чогултам, Java жана жалпысынан IT тармагын өнүктүрүү жөнүндө ойлорду жазам. Жазылгансызбы? Абдан жакшы! Мейли, эми кетели!
Mapstruct, FQ?
Ыкчам типтеги коопсуз төө буурчак карталары үчүн code генератору. Биздин биринчи милдет Mapstruct деген эмне экенин жана ал эмне үчүн керек экенин аныктоо. Жалпысынан алганда, бул тууралуу расмий сайттан окуй аласыз. Сайттын башкы бетинде суроолорго үч жооп бар: бул эмне? Эмне үчүн? Кантип? Муну да жасоого аракет кылабыз:
Бул эмне?
Mapstruct – бул интерфейстер аркылуу сүрөттөлгөн конфигурациялардын негизинде түзүлгөн codeду колдонуу менен кээ бир an objectилердин an objectтерин башка an objectтердин an objectилерине картага түшүрүүгө (карта, жалпысынан алганда, алар дайыма ушундай дешет: карта, карта ж.б.) жардам берген китепкана.
Эмне үчүн?
Көпчүлүк учурда, биз көп катмарлуу тиркемелерди (маалымат базасы менен иштөө үчүн катмар, бизнес логика катмары, тиркеменин тышкы дүйнө менен өз ара аракеттенүү катмары) иштеп чыгабыз жана ар бир катмардын маалыматтарды сактоо жана иштетүү үчүн өзүнүн an objectтери бар. . Жана бул маалыматтар бир an objectтен экинчисине өтүү аркылуу катмардан катмарга өтүшү керек. Бул ыкма менен иштебегендер үчүн бул бир аз татаал сезorши мүмкүн. Мисалы, бизде Студенттик маалымат базасы бар. Бул an objectтин маалыматтары бизнес-логикалык (кызматтар) катмарына өткөндө, биз Студент классынан StudentModel классына маалыматтарды өткөрүп беришибиз керек. Андан кийин, бизнес логикасы менен бардык манипуляциялардан кийин, маалыматтарды сыртка чыгаруу керек. Бул үчүн бизде StudentDto классы бар. Албетте, биз StudentModel классынан StudentDtoга маалыматтарды өткөрүп беришибиз керек. Которула турган ыкмаларды ар бир жолу кол менен жазуу эмгекти кеп талап кылат. Мындан тышкары, бул code базасында сакталышы керек болгон кошумча code. Сиз ката кетириши мүмкүн. Жана Mapstruct мындай ыкмаларды компиляция стадиясында жаратат жана аларды түзүлгөн булактарда сактайт.
Кантип?
Аннотацияларды колдонуу. Биз жөн гана китепканага бул интерфейстеги ыкмаларды бир an objectтен экинчи an objectке которуу үчүн колдонсо болорун билдирген негизги 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 туура деп эсептелбейт жана тестирлөөгө алынbyte, бул өндүрүшкө алынbyte жана иштеп чыгуучу ишти аягына чыгара элек дегенди билдирет. Иши күмөнсүз китепканага тест жазуунун эмне кереги бар? Бирок биз тест жазуубуз керек, анткени биз картачыны канчалык туура сүрөттөгөнүбүздү жана ал биз күткөн нерсени аткарып жатабы же жокпу, текшерип жатабыз. Биринчиден, ишибизди жеңилдетүү үчүн, келгиле, pom.xml файлына дагы бир көз карандылыкты кошуп, Ломбокту долбоорубузга кошолу:
Биздин долбоордо биз моделдик класстардан (бизнес логикасы менен иштөө үчүн колдонулат) тышкы дүйнө менен байланышуу үчүн колдонгон DTO класстарына өтүшүбүз керек болот. Биздин жөнөкөйлөтүлгөн versionда биз талаалар өзгөрбөйт жана биздин картачылар жөнөкөй болот деп ойлойбуз. Бирок, каалоо бар болсо, Mapstruct менен кантип иштөө керек, аны кантип конфигурациялоо керек жана анын артыкчылыктарынан кантип пайдалануу керектиги жөнүндө кененирээк макала жазса болот. Бирок, анда, анткени бул макала бир топ узун болот. Бизде бир студент бар дейли, ал катышкан лекциялардын жана лекторлордун тизмеси. Үлгү пакетин түзөлү . Мунун негизинде биз жөнөкөй моделди түзөбүз:
Эми лекция моделдеринин жыйнагын DTO лекцияларынын жыйнагына которо турган мапперди түзөлү. Биринчи нерсе - долбоорго Mapstruct кошуу. Бул үчүн, биз алардын расмий сайтын колдонобуз , баары ошол жерде сүрөттөлгөн. Башкача айтканда, биз эс тутумубузга бир көз карандылыкты жана плагинди кошушубуз керек (эгерде эс тутум деген эмне жөнүндө суроолоруңуз болсо, анда 1-берене жана 2-берене ):
Андан кийин, dto жана моделдин жанында карталоочу пакетти түзөлү . Биз буга чейин көрсөткөн класстардын негизинде дагы беш картачы түзүшүңүз керек болот:
Мапперлерде биз башка картачыларга кайрыла турганыбызды өзүнчө белгилей кетүү керек. Бул StudentMapperде жасалгандай, Картачынын annotationсындагы uses талаасы аркылуу жасалат :
Бул жерде биз лекциялардын тизмесин жана лекторлордун тизмесин туура картага түшүрүү үчүн эки картаны колдонобуз. Эми биз codeубузду түзүп, ал жерде эмне жана кантип бар экенин көрүшүбүз керек. Бул mvn clean compile буйругун колдонуу менен жасалышы мүмкүн . Бирок, белгилүү болгондой, биздин картачылардын Mapstruct ишке ашырууларын түзүп жатканда, картанын ишке ашыруулары талаалардын үстүнөн жазган эмес. Неге? Ломбоктон Data annotationсын алуу мүмкүн эмес экени белгилүү болду. Анан бир нерсе кылуу керек эле... Ошондуктан макалада жаңы бөлүм ачылды.
Lombok жана Mapstruct байланыштыруу
Бир нече мүнөттүк издөөдөн кийин биз Lombok менен Mapstructти белгилүү бир жол менен туташтырышыбыз керек экен. Бул тууралуу Mapstruct documentациясында маалымат бар . Mapstruct иштеп чыгуучулары тарабынан сунушталган мисалды карап чыккандан кийин, келгиле, pom.xml жаңырталы: Келгиле, өзүнчө versionларды кошолу:
Ушундан кийин баары иштеши керек. Долбоорубузду дагы бир ирет түзөлү. Бирок Mapstruct түзгөн класстарды кайдан тапса болот? Алар түзүлгөн булактарда: ${projectDir}/target/generated-sources/annotations/ Mapstruct постунан менин көңүлүм калганын түшүнүүгө даярбыз, келгиле, картачылар үчүн тесттерди түзүүгө аракет кылалы.
Биз картачыларыбызга тест жазабыз
Мен интегралдык тест түзүп жаткан учурда картачылардын бирин сынай турган тез жана жөнөкөй тест түзөм жана анын бүтүү убактысы жөнүндө кабатыр болбо:
Бул жерде, SpringBootTest annotationсын колдонуп, биз толугу менен applicationContextди ишке киргизебиз жана андан Autowired annotationсын колдонуп, тестирлөө үчүн керектүү классты чыгарып алабыз. Тестирлөөнүн ылдамдыгы жана оңойлугу жагынан бул абдан жакшы. Сыноо ийгorктүү өттү, баары жакшы. Бирок биз башка жол менен барабыз жана картачы үчүн бирдик тестин жазабыз, мисалы, LectureListMapper...
Mapstruct жараткан ишке ашыруулар биздин долбоор менен бир класста болгондуктан, биз аларды тесттерибизде оңой колдоно алабыз. Баары сонун көрүнөт - annotationлар жок, биз эң жөнөкөй жол менен керектүү классты түзөбүз. Бирок биз тестти иштеткенде, анын бузулуп каларын жана консолдо NullPointerException болорун түшүнөбүз... Себеби, LectureListMapper картасын ишке ашыруу төмөнкүдөй көрүнөт:
Эгерде биз NPE (NullPointerException үчүн кыска) карасак, биз аны lectureMapper өзгөрмөсүнөн алабыз , ал инициализацияланбаган болуп чыгат. Бирок биздин ишке ашырууда бизде өзгөрмөлөрдү инициализациялоочу конструктор жок. Mapstruct картачыны ушундай жол менен ишке ашырганынын себеби дал ушул! Жазында төө буурчакты класстарга бир нече жол менен кошо аласыз, сиз аларды талаа аркылуу, жогоруда айтылгандай, Autowired annotationсы менен сайсаңыз болот же конструктор аркылуу сайсаңыз болот. Тестти аткаруу убактысын оптималдаштыруу керек болгондо, мен жумушта ушундай көйгөйлүү кырдаалга туш болдум. Эч нерсе кыла алbyte деп ойлоп, телеграм каналыма сыздадым. Анан алар мага комментарийлерде жардам берип, инъекциянын стратегиясын ыңгайлаштырууга болот дешти. Mapper интерфейсинде injectionStrategy талаасы бар , ал жөн гана InjectionStrategy аталышын кабыл алат , анын эки мааниси бар: FIELD жана CONSTRUCTOR . Эми, муну бorп туруп, бул жөндөөнү картачыларыбызга кошолу; Мен аны LectureListMapper аркылуу мисал катары көрсөтөм :
Кошумча бөлүгүн кара шрифт менен белгилеп койдум. Келгиле, бул параметрди башкалардын бардыгына кошолу жана картачылар жаңы линия менен түзүлүшү үчүн долбоорду кайра компиляция кылалы. Бул аткарылгандан кийин, келгиле, LectureListMapper үчүн картаны ишке ашыруу кандайча өзгөргөнүн карап көрөлү (бизге керектүү бөлүгү калың менен белгиленген):
Азыр Mapstruct конструктор аркылуу карта инъекциясын ишке ашырды. Дал ушул нерсеге жетишүүгө аракет кылганбыз. Эми биздин тест компиляцияны токтотот, аны жаңырталы жана алалы:
Эми биз тестти өткөрсөк, баары күтүлгөндөй иштейт, анткени LectureListMapperImplде биз ага керектүү LectureMapper тапшырабыз... Жеңиш! Бул силер үчүн кыйын эмес, бирок мен ыраазымын: Достор, баары адаттагыдай эле, менин GitHub аккаунтума , Telegram аккаунтума жазылыңыз . Ал жерде мен өзүмдүн ишмердүүлүгүмдүн жыйынтыгын жарыялайм, чынында эле пайдалуу нерселер бар) Мен сиздерди өзгөчө телеграм каналынын талкуу тобуна кошулууга чакырам . Кимдир бирөөнүн техникалык суроосу болсо, ошол жерден жооп ала тургандай болуп калат. Бул формат баарына кызык, ким эмнени билет экенин окуп, тажрыйба топтосо болот.
Корутунду
Бул макаланын алкагында биз Mapstruct сыяктуу керектүү жана көп колдонулган продукт менен тааныштык. Биз бул эмне экенин, эмне үчүн жана кантип түшүндүк. Чыныгы мисалды колдонуп, биз эмне кылса болорун жана аны кантип өзгөртүүгө болорун сездик. Биз ошондой эле конструктор аркылуу төө буурчак инъекциясын кантип орнотууну карап чыктык, андыктан картачыларды туура сынап көрүүгө болот. Mapstruct'тин кесиптештери өз продуктунун колдонуучуларына карта салгычтарды кантип инъекциялоону так тандоого мүмкүндүк берди, бул үчүн биз аларга ыраазычылык билдиребиз. БИРОК, Spring төө буурчакты конструктор аркылуу инъекциялоону сунуш кылганына карабастан, Mapstructтин балдары демейки боюнча талаа аркылуу инъекцияны орнотушкан. Эмнеге андай? Жооп жок. Биз билбеген себептер болушу мүмкүн деп ойлойм, ошондуктан алар ушундай кылышты. Жана алардан билүү үчүн, мен алардын расмий продукт репозиторийинде GitHub маселесин түздүм.
GO TO FULL VERSION