My Profile Photo

Mehmet Cem Yücel


Technical Writings.
Architecture, Security, Java, Golang, Devops, Microservices, Spring Boot, Kafka, Distributed Systems and Blockchain


MapStruct ile SpringBoot Obje Dönüşümü

Bu yazımızda MapStruct isimli Java Bean Mapper kütüphanesini ve Spring ile kullanımını inceleyeceğiz.

1. Giriş

Kodlama yaparken ihtiyaç duyduğumuz bilgileri nesnelerimizin içerisindeki alanlarda tutarız. Nesneye dayalı programlama paradigmasına göre yaptığımız tüm tasarımlar dış dünya ile iletişim noktasına geldiğimizde birebir örtüşmeyebilir. Devraldığınız bir projede tasarladığınız bir POJO(Plain Old Java Object), veritabanındaki varlık modeliyle(**ER**: Entity Relationship Model) örtüşmeyebileceği gibi dış servislerden aldığınız DTO (Data Transfer Object) nesneler de sizin iç tasarımınızla birebir örtüşmeyecektir. Bu gibi durumlarda birden fazla obje katmanları (entity, DTO, vb..) yaratarak kendi kodumuzu dış dünyanın etkilerinden korumaya çalışırız. Ancak her ihtiyaç duyduğumuzda bu nesneleri birbirlerine dönüştürmek geliştirme maliyeti açısından zaman çalan bir işlemdir.

MapStruct bu ihtiyacımızı derleme zamanında kolayca karşılayan ve bizim için mapper sınıfları yaratan bir kütüphane. Arayüzler aracılığıyla kaynak ve hedef **POJO** sınıflarının nasıl eşitleneceğini tasarlayabilirsiniz. Başka bir yöntem olarak sadece annotationlar kullanarak **Spring** ile bu işi nasıl inceleyeceğimizi aşağıda inceleyeceğiz.

2. Bağımlılıklar

Maven için pom.xml dosyasına aşağıdaki bağımlılığı ve yapılandırmayı ekliyoruz.

Bağımlılıkların yanı sıra eklememiz gereken bir yapılandırma daha var. MapStruct derleme zamanında çalışan bir araç. Biz bu yazımızda Spring Boot ile annotation’lar aracılığı ile bu toolu nasıl kullanabileceğimizi inceliyoruz. Bu sebeple Spring Boot Maven Plugin’inin annotation processor’lerine MapStruct’ın processor’unu eklememiz lazım. Bu sayede Spring Boot Maven Plugin’i derleme esnasında MapStruct Interface’leri tarayıp birazdan yapacağımız yapılandırmaların yönlendirmesinde yeni sınıflar oluşturulmasını sağlayacak.

3. Klonlayıcı

3.1. POJO Sınıfı

İçerisinde primitive ve complex tiplerin olduğu basit bir sınıf oluşturalım.

3.2. Cloner Arayüzü

clone isimli metod ile girdisi ve çıktısı aynı olan bir interface ile bir nesnenin yeni hash ile klonunu yaratmanız MapStruct ile oldukça kolay.

ÖNEMLİ NOT: MapStruct arayüzlerinde tanımladığınız mapperların sınıflarının bytecode’larının oluşması için maven clean install komutunu çalıştırabilirsiniz. Aksi taktirde Spring byte kodu runtime da bulamayacak ClassNotFoundException: Cannot find implementation for …..Mapper gibi bir hata verecektir.

3.3. Test Senaryosu

Bir nesne örneği yaratıp mapper’a klonlattığımızda aynı değerlere sahip yeni bir nesne dönecektir.

4. Kalıtıcı

Herhangi bir kalıtım hiyerarşisinde olmasa dahi aynı isimli alanlara ve getter/setterlara sahip iki sınıf arasında kolay bir dönüşüm yapılabilir.

4.1. POJO Sınıfları

Kaynak sınıf olarak InheritDTO , hedef sınıf olarak InheritObject sınıflarını ele alalım.

4.2. Inherit Arayüzü

Farkındaysanız hedef sınıfımızda kaynak sınıfımızda bulunmayan alanlar mevcut. Bu durumda @InheritInverseConfiguration annotationı ile işaretlediğimiz metod imzasına ait kodlar aynı getter setter’lar ile eşleyebildiği kadar veriyi eşitleyip geri kalanları için default değerlerinde bırakacaklardır. Veya dilerseniz alanlar için default değerleri siz de verebilirsiniz.

4.3. Test Senaryosu

Aşağıdaki testleri çalıştırarak senaryomuzun çalıştığını gözlemleyebiliriz.

5. Alan Alan Eşitleyici

Aynı veri tipindeki farklı field isimlerine sahip sınıfları eşitlemek de mümkündür. Bunun için aşağıdaki sınıfları oluşturalım.

5.1. POJO Sınıfları

Değişken isimlerimiz farklı ancak alan tiplerimiz aynı ise aşağıdaki gibi bir mapper düzenlememiz gereklidir.

5.2. TypeSafe Arayüzü

@Mappings annotation’ı ile tek tek hangi alanın hedef sınıftaki hangi alana eşitlenmesini istediğimizi belirtiyoruz.

5.3. Test Senaryosu

6. Tip Dönüştürücü

Sadece aynı tipte olması gerekmeksizin farklı değerlere ve isimlere sahip sınıfları da birbirlerine dönüştürmemiz mümkündür.

6.1. POJO Sınıfları

6.2. Mapper Arayüzü

Yukarıdaki mapperdaki gibi formatını verdiğimiz bir Instant, Date gibi tarih tiplerinin dönüşümünü sağlamamız mümkün.

6.3. Test Senaryosu

7. Sonuç

Giriş niteliğindeki bu yazının haricinde MapStruct’ın farklı birçok mappingi yapabildiğini hatırlatmakta fayda var. Expression_’_lar ile mappingler yapabileceğiniz gibi has a ilişkisine sahip sınıflarda da mappinler yapabilirsiniz. Veya Abstract sınıflar ile tamamen manuel mappingler de yapabilirsiniz.

MapStruct bütün bu özelliklerin dışında Lombok ,Kotlin, Gradle, JPA gibi farklı teknolojiler ve araçlara da destek sağlıyor. Ayrıca Eclipse ve IntelliJ gibi popüler IDE ‘lere de uyumlu şekilde çalışabiliyor. Github sayfasında farklı örnekleri de inceleyebilirsiniz.

Java diğer mapper toollarıyla kıyaslandığında MapStruct performansıyla denemeye başlamak için çok şey vaadediyor. Bu kıyaslamalarla ilgili örnek bir yazıya buradan ulaşabilirsiniz.

Projenin kodlarına buradan erişebilirsiniz.




May interest this topics

If you interested in Blockchain Technologies,


comments powered by Disqus