MapStruct একটি শক্তিশালী Java মডেল মেপিং টুল যা ডোমেইন অবজেক্ট এবং ডেটা ট্রান্সফার অবজেক্ট (DTO) এর মধ্যে দ্রুত এবং কার্যকরী ম্যাপিং করতে ব্যবহৃত হয়। এর ডিফল্ট ম্যাপিং ফিচারগুলি বেশিরভাগ পরিস্থিতি পূরণ করতে সক্ষম হলেও, অনেক সময় কাস্টম ম্যাপিং লজিক বা কনভার্শন প্রক্রিয়ার প্রয়োজন হয়। এই প্রক্রিয়াগুলির জন্য MapStruct কাস্টম ম্যাপিং এবং কনভার্শন তৈরির সুযোগ দেয়, যা নির্দিষ্ট পরিস্থিতির জন্য বিশেষ লজিক প্রয়োগ করতে সাহায্য করে।
এই টিউটোরিয়ালে, আমরা Custom Mapping এবং এর প্রয়োজনীয়তা সম্পর্কে বিস্তারিতভাবে আলোচনা করব, এবং বুঝব কেন এবং কখন কাস্টম ম্যাপিং ব্যবহৃত হয়।
১. Custom Mapping এর প্রয়োজনীয়তা
Custom Mapping প্রয়োজন হয় যখন:
- Default Mapping Workflows যথেষ্ট নয়: মাভেন বা ডিফল্ট ম্যাপিং লজিক ব্যবহার করলে কিছু বিশেষ ক্ষেত্রের জন্য আপনি কাঙ্ক্ষিত ফলাফল পেতে পারেন না।
- Data Transformation এর জন্য কাস্টম লজিক দরকার: ডোমেইন অবজেক্টের মধ্যে ফিল্ডগুলির মান ট্রান্সফর্ম করা হয়, কিন্তু কিছু ক্ষেত্রের জন্য কাস্টম কনভার্শন দরকার হতে পারে, যেমন date format conversion বা currency conversion।
- Non-trivial Fields: কখনো কখনো ফিল্ডগুলির মধ্যে সরাসরি ম্যাপিং করা সম্ভব হয় না। যেমন, দুটি ফিল্ডের নাম একই না হলেও, তাদের মান একে অপরের সাথে সম্পর্কিত।
- Complex Logic for Mapping: কোনো ফিল্ডের মান থেকে অন্য একটি ফিল্ডের মান নির্ধারণ করতে খুবই জটিল বা নির্দিষ্ট লজিকের প্রয়োজন হতে পারে।
উদাহরণ:
ধরা যাক, আপনার কাছে একটি Person ডোমেইন অবজেক্ট রয়েছে, যার মধ্যে একটি fullName ফিল্ড আছে, এবং আপনি এটি দুটি আলাদা ফিল্ডে, firstName এবং lastName এ ডিভাইড করতে চান।
এই কাজটি যদি মাভেন বা ডিফল্ট ম্যাপিং দ্বারা করা হয়, তবে তা কার্যকর হবে না, কারণ MapStruct সরাসরি একটি ফিল্ডকে দুইটি ফিল্ডে ভেঙে ফেলতে পারে না। এই পরিস্থিতিতে কাস্টম ম্যাপিং ব্যবহার করতে হবে।
২. Custom Mapping কিভাবে তৈরি করবেন?
MapStruct কাস্টম ম্যাপিং তৈরি করার জন্য @Mapping অ্যানোটেশন এবং expression অথবা qualifiedByName ব্যবহার করার সুযোগ দেয়। কাস্টম ম্যাপিংয়ের মাধ্যমে আপনি আপনার নিজের কনভার্টার বা ম্যাপিং লজিক তৈরি করতে পারেন।
উদাহরণ ১: Field-to-Field Custom Mapping (ফিল্ড থেকে ফিল্ড)
ধরা যাক, আপনার Person ডোমেইন অবজেক্টে একটি fullName ফিল্ড রয়েছে, এবং আপনি এটি দুটি পৃথক ফিল্ডে firstName এবং lastName এ ভেঙে ম্যাপ করতে চান।
Person.java (Domain Object):
public class Person {
private String fullName;
// Getters and Setters
}
PersonDTO.java (DTO):
public class PersonDTO {
private String firstName;
private String lastName;
// Getters and Setters
}
PersonMapper.java (Mapper Interface):
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper
public interface PersonMapper {
@Mapping(target = "firstName", expression = "java(person.getFullName().split(\" \")[0])")
@Mapping(target = "lastName", expression = "java(person.getFullName().split(\" \")[1])")
PersonDTO personToPersonDTO(Person person);
}
এখানে, @Mapping অ্যানোটেশন ব্যবহার করে কাস্টম এক্সপ্রেশন নির্ধারণ করা হয়েছে যা fullName থেকে প্রথম নাম (firstName) এবং শেষ নাম (lastName) বের করবে।
উদাহরণ ২: Custom Method with @Named (নামের সাহায্যে কাস্টম মেথড)
MapStruct এর @Named অ্যানোটেশন ব্যবহার করে আপনি কাস্টম মেথডও তৈরি করতে পারেন, যা ডেটার কনভার্সনের জন্য ব্যবহৃত হবে।
Person.java (Domain Object):
public class Person {
private String birthDate;
// Getters and Setters
}
PersonDTO.java (DTO):
public class PersonDTO {
private String birthDateFormatted;
// Getters and Setters
}
PersonMapper.java (Mapper Interface):
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
@Mapper
public interface PersonMapper {
@Mapping(source = "birthDate", target = "birthDateFormatted", qualifiedByName = "formatBirthDate")
PersonDTO personToPersonDTO(Person person);
@Named("formatBirthDate")
default String formatBirthDate(String birthDate) {
// Assuming birthDate is in "yyyy-MM-dd" format
// and converting it to "dd-MM-yyyy"
return birthDate.split("-")[2] + "-" + birthDate.split("-")[1] + "-" + birthDate.split("-")[0];
}
}
এখানে, formatBirthDate মেথড কাস্টম লজিকের মাধ্যমে birthDate ফিল্ডকে ফরম্যাট করছে, এবং @Named অ্যানোটেশন ব্যবহার করে মেথডটি MapStruct এর মধ্যে ব্যবহার করা হচ্ছে।
৩. Custom Mapping এর প্রভাব
- Data Transformation: যখন একটি ফিল্ডের মান অন্য ফিল্ডে রূপান্তরিত করতে হয় (যেমন তারিখ বা স্ট্রিং ফরম্যাট পরিবর্তন), কাস্টম ম্যাপিং প্রয়োজন হয়।
- Complex Mapping Logic: কখনো কখনো আপনি একটি ফিল্ড থেকে অন্য ফিল্ডে সরাসরি ম্যাপিং করতে পারেন না, কারণ ডেটার ফরম্যাট বা কন্টেন্টের মধ্যে পরিবর্তন থাকতে পারে।
- Performance Considerations: কাস্টম ম্যাপিং ব্যবহার করে, আপনি কোডে ম্যানুয়ালি লজিক যুক্ত করতে পারেন, যা আরও কার্যকরী এবং পারফরম্যান্সে সহায়ক হতে পারে, বিশেষ করে যখন ডেটা বড় বা জটিল হয়।
৪. MapStruct এ কাস্টম মেথডস ব্যবহার করার সুবিধা
- Customization: কাস্টম লজিক ব্যবহার করে আপনি ম্যাপিং প্রক্রিয়াকে সম্পূর্ণ কাস্টমাইজ করতে পারেন।
- Maintainability: কাস্টম কনভার্সন ফাংশন বা ম্যাপিং মেথড দ্বারা কোডের পুনঃব্যবহারযোগ্যতা এবং রক্ষণাবেক্ষণ সহজ হয়।
- Type Safety: MapStruct টাইপ সেফটি প্রদান করে, অর্থাৎ, আপনি কাস্টম মেথড এবং কাস্টম ম্যাপিং লজিক প্রয়োগ করলেও টাইপ সম্পর্কিত ত্রুটি থেকে রক্ষা পাবেন।
- Integration with External Libraries: আপনি কাস্টম কনভার্সন প্রক্রিয়ায় বাইরের লাইব্রেরি ব্যবহার করতে পারেন, যেমন ডেটা ফরম্যাট কনভার্শন লাইব্রেরি।
সারাংশ
Custom Mapping MapStruct এর একটি অত্যন্ত গুরুত্বপূর্ণ বৈশিষ্ট্য, যা আপনাকে আপনার প্রোজেক্টের ম্যাপিং প্রক্রিয়ায় কাস্টম লজিক এবং কনভার্সন প্রয়োগ করতে সহায়তা করে। যখন ডোমেইন অবজেক্ট এবং DTO এর মধ্যে সরাসরি ম্যাপিং সম্ভব হয় না বা একটি বিশেষ ট্রান্সফরমেশন প্রয়োজন হয়, তখন Custom Mapping ব্যবহৃত হয়। MapStruct কাস্টম মেথড এবং @Mapping অ্যানোটেশন ব্যবহার করে এসব কাস্টম লজিক সহজেই প্রয়োগ করা যায়, যা ডেটা এক্সচেঞ্জ এবং ট্রান্সফরমেশনকে আরো কার্যকরী এবং স্বচ্ছ করে তোলে।
Read more