Custom Mapping এবং Conversion গাইড ও নোট

Java Technologies - ম্যাপস্ট্রাক্ট (MapStruct)
304

MapStruct হল একটি শক্তিশালী Java লাইব্রেরি যা মূলত JavaBeans (POJOs) এর মধ্যে অটোমেটিক ডেটা ম্যাপিং পরিচালনা করে। এটি compile-time এ কোড জেনারেট করে এবং টাইপ-সেফ ম্যাপিং প্রদান করে। যদিও MapStruct ডিফল্টভাবে সাধারণ ক্ষেত্রগুলির জন্য ম্যাপিং পরিচালনা করতে পারে, তবে কখনও কখনও আপনার কাস্টম লজিক প্রয়োগ করতে হতে পারে, যেখানে Custom Mapping এবং Conversion দরকার পড়ে।

এই গাইডে, আমরা MapStruct এর মাধ্যমে Custom Mapping এবং Conversion কিভাবে পরিচালনা করা যায়, তা দেখব।


১. Custom Mapping (কাস্টম ম্যাপিং)

কাস্টম ম্যাপিং তখন ব্যবহার করা হয় যখন MapStruct এর ডিফল্ট ম্যাপিং কার্যকরী না হয়, বা আপনি কিছু নির্দিষ্ট লজিক প্রয়োগ করতে চান। উদাহরণস্বরূপ, যদি আপনি একটি একক ফিল্ডের মান পরিবর্তন করতে চান বা দুটি ফিল্ডের মান একত্রিত করতে চান, তবে কাস্টম ম্যাপিং ব্যবহার করা যেতে পারে।

উদাহরণ: কাস্টম ম্যাপিং

ধরা যাক, আমাদের দুটি ক্লাস Person এবং PersonDTO রয়েছে, এবং আমরা Person থেকে PersonDTO তে একটি কাস্টম লজিকের মাধ্যমে ম্যাপিং করতে চাই, যেখানে firstName এবং lastName ফিল্ডগুলি fullName হিসেবে একটি ফিল্ডে যুক্ত করা হবে।

Person.java:

public class Person {
    private String firstName;
    private String lastName;
    
    // Getters and Setters
}

PersonDTO.java:

public class PersonDTO {
    private String fullName;
    
    // Getters and Setters
}

এখন, MapStruct ব্যবহার করে firstName এবং lastName ফিল্ডের মানকে fullName ফিল্ডে কনভার্ট করতে হবে। এই কনভার্সন করতে আমরা MapStruct এর কাস্টম ম্যাপিং ব্যবহার করব।

PersonMapper.java (Custom Mapping Example):

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper
public interface PersonMapper {
    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);

    // Custom mapping: Concatenate firstName and lastName into fullName
    @Mapping(target = "fullName", expression = "java(person.getFirstName() + \" \" + person.getLastName())")
    PersonDTO personToPersonDTO(Person person);
}

এখানে, @Mapping অ্যানোটেশনের মাধ্যমে আমরা কাস্টম ম্যাপিং লজিক প্রয়োগ করেছি, যা firstName এবং lastName ফিল্ডের মানকে fullName ফিল্ডে একত্রিত করবে।

Usage Example:

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.setFirstName("John");
        person.setLastName("Doe");

        // Perform custom mapping
        PersonDTO personDTO = PersonMapper.INSTANCE.personToPersonDTO(person);
        System.out.println("Full Name: " + personDTO.getFullName());
    }
}

Output:

Full Name: John Doe

এখানে, firstName এবং lastName একত্রিত হয়ে fullName তে রূপান্তরিত হয়েছে।


২. Conversion (কনভার্সন)

MapStruct ব্যবহার করে আপনি কাস্টম কনভার্টার তৈরি করতে পারেন, যা ডেটা টাইপ কনভার্ট করতে সহায়তা করে। উদাহরণস্বরূপ, আপনি যদি একটি String টাইপের মানকে একটি Date টাইপে কনভার্ট করতে চান, তবে Custom Conversion মেথড ব্যবহার করতে পারেন।

উদাহরণ: কাস্টম কনভার্টার

ধরা যাক, আমরা একটি String থেকে Date কনভার্ট করতে চাই। আমরা MapStruct এর মাধ্যমে একটি কাস্টম কনভার্টার তৈরি করব।

StringToDateConverter.java:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Optional;

public class StringToDateConverter {

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    public Date convert(String dateString) {
        try {
            return Optional.ofNullable(dateString)
                           .map(date -> {
                               try {
                                   return dateFormat.parse(date);
                               } catch (Exception e) {
                                   return null;
                               }
                           })
                           .orElse(null);
        } catch (Exception e) {
            return null;
        }
    }
}

এখানে, আমরা String থেকে Date কনভার্ট করতে SimpleDateFormat ব্যবহার করছি। convert() মেথডে, এটি yyyy-MM-dd ফরম্যাটের তারিখ স্ট্রিং কনভার্ট করবে।

PersonMapper.java (Using Custom Converter)

এখন, আমরা এই কনভার্টারকে MapStruct মেপিংয়ে ব্যবহার করব।

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper(uses = StringToDateConverter.class)
public interface PersonMapper {
    PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);

    @Mapping(target = "birthDate", source = "birthDateString")
    PersonDTO personToPersonDTO(Person person);
}

এখানে, birthDateString (String) ফিল্ডটি StringToDateConverter এর মাধ্যমে birthDate (Date) ফিল্ডে কনভার্ট হবে।

Person.java:

public class Person {
    private String firstName;
    private String lastName;
    private String birthDateString;  // String representation of date
    
    // Getters and Setters
}

PersonDTO.java:

import java.util.Date;

public class PersonDTO {
    private String fullName;
    private Date birthDate;  // Date object
    
    // Getters and Setters
}

Usage Example

public class Main {
    public static void main(String[] args) {
        Person person = new Person();
        person.setFirstName("John");
        person.setLastName("Doe");
        person.setBirthDateString("1990-05-15");

        // Perform mapping
        PersonDTO personDTO = PersonMapper.INSTANCE.personToPersonDTO(person);
        System.out.println("Full Name: " + personDTO.getFullName());
        System.out.println("Birth Date: " + personDTO.getBirthDate());
    }
}

Output:

Full Name: John Doe
Birth Date: Mon May 15 00:00:00 UTC 1990

এখানে, birthDateString ফিল্ডটি StringToDateConverter ব্যবহার করে Date টাইপে কনভার্ট হয়ে birthDate ফিল্ডে চলে গেছে।


৩. MapStruct Custom Mapping এবং Conversion এর সুবিধা

  • Code Generation: MapStruct স্বয়ংক্রিয়ভাবে ম্যাপিং কোড তৈরি করে, ফলে ডেভেলপারকে ম্যানুয়াল কোড লেখার প্রয়োজন হয় না।
  • Performance: Compile-time কোড জেনারেশন করে MapStruct রানটাইম পারফরম্যান্সে কোনো প্রভাব ফেলে না।
  • Custom Logic: কাস্টম ম্যাপিং এবং কনভার্সন যুক্ত করে আপনি আপনার প্রয়োজন অনুযায়ী লজিক প্রয়োগ করতে পারেন।
  • Flexibility: MapStruct কাস্টম কনভার্টার এবং কাস্টম মেথডের মাধ্যমে বিস্তৃত কাস্টমাইজেশন সুবিধা প্রদান করে।
  • Type Safety: টাইপ সেফটি নিশ্চিত করে MapStruct, ফলে কম সময়ে কম ত্রুটি সহ কোড লেখা যায়।

সারাংশ

MapStruct ব্যবহার করে আপনি সহজেই Custom Mapping এবং Conversion করতে পারেন। এটি সাধারণ ম্যাপিংয়ের পাশাপাশি কাস্টম কনভার্সন এবং ম্যাপিং লজিক প্রয়োগের সুযোগ দেয়। MapStruct এর মাধ্যমে String থেকে Date, Enum থেকে String, এবং অন্যান্য কাস্টম কনভার্সন খুব সহজে করা যায়, যা আপনার কোডের কার্যকারিতা এবং মান উন্নত করতে সাহায্য করে।


Content added By

Custom Mapping এর প্রয়োজনীয়তা

253

MapStruct একটি শক্তিশালী Java মডেল মেপিং টুল যা ডোমেইন অবজেক্ট এবং ডেটা ট্রান্সফার অবজেক্ট (DTO) এর মধ্যে দ্রুত এবং কার্যকরী ম্যাপিং করতে ব্যবহৃত হয়। এর ডিফল্ট ম্যাপিং ফিচারগুলি বেশিরভাগ পরিস্থিতি পূরণ করতে সক্ষম হলেও, অনেক সময় কাস্টম ম্যাপিং লজিক বা কনভার্শন প্রক্রিয়ার প্রয়োজন হয়। এই প্রক্রিয়াগুলির জন্য MapStruct কাস্টম ম্যাপিং এবং কনভার্শন তৈরির সুযোগ দেয়, যা নির্দিষ্ট পরিস্থিতির জন্য বিশেষ লজিক প্রয়োগ করতে সাহায্য করে।

এই টিউটোরিয়ালে, আমরা Custom Mapping এবং এর প্রয়োজনীয়তা সম্পর্কে বিস্তারিতভাবে আলোচনা করব, এবং বুঝব কেন এবং কখন কাস্টম ম্যাপিং ব্যবহৃত হয়।


১. Custom Mapping এর প্রয়োজনীয়তা

Custom Mapping প্রয়োজন হয় যখন:

  1. Default Mapping Workflows যথেষ্ট নয়: মাভেন বা ডিফল্ট ম্যাপিং লজিক ব্যবহার করলে কিছু বিশেষ ক্ষেত্রের জন্য আপনি কাঙ্ক্ষিত ফলাফল পেতে পারেন না।
  2. Data Transformation এর জন্য কাস্টম লজিক দরকার: ডোমেইন অবজেক্টের মধ্যে ফিল্ডগুলির মান ট্রান্সফর্ম করা হয়, কিন্তু কিছু ক্ষেত্রের জন্য কাস্টম কনভার্শন দরকার হতে পারে, যেমন date format conversion বা currency conversion
  3. Non-trivial Fields: কখনো কখনো ফিল্ডগুলির মধ্যে সরাসরি ম্যাপিং করা সম্ভব হয় না। যেমন, দুটি ফিল্ডের নাম একই না হলেও, তাদের মান একে অপরের সাথে সম্পর্কিত।
  4. 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 এর প্রভাব

  1. Data Transformation: যখন একটি ফিল্ডের মান অন্য ফিল্ডে রূপান্তরিত করতে হয় (যেমন তারিখ বা স্ট্রিং ফরম্যাট পরিবর্তন), কাস্টম ম্যাপিং প্রয়োজন হয়।
  2. Complex Mapping Logic: কখনো কখনো আপনি একটি ফিল্ড থেকে অন্য ফিল্ডে সরাসরি ম্যাপিং করতে পারেন না, কারণ ডেটার ফরম্যাট বা কন্টেন্টের মধ্যে পরিবর্তন থাকতে পারে।
  3. Performance Considerations: কাস্টম ম্যাপিং ব্যবহার করে, আপনি কোডে ম্যানুয়ালি লজিক যুক্ত করতে পারেন, যা আরও কার্যকরী এবং পারফরম্যান্সে সহায়ক হতে পারে, বিশেষ করে যখন ডেটা বড় বা জটিল হয়।

৪. MapStruct এ কাস্টম মেথডস ব্যবহার করার সুবিধা

  1. Customization: কাস্টম লজিক ব্যবহার করে আপনি ম্যাপিং প্রক্রিয়াকে সম্পূর্ণ কাস্টমাইজ করতে পারেন।
  2. Maintainability: কাস্টম কনভার্সন ফাংশন বা ম্যাপিং মেথড দ্বারা কোডের পুনঃব্যবহারযোগ্যতা এবং রক্ষণাবেক্ষণ সহজ হয়।
  3. Type Safety: MapStruct টাইপ সেফটি প্রদান করে, অর্থাৎ, আপনি কাস্টম মেথড এবং কাস্টম ম্যাপিং লজিক প্রয়োগ করলেও টাইপ সম্পর্কিত ত্রুটি থেকে রক্ষা পাবেন।
  4. Integration with External Libraries: আপনি কাস্টম কনভার্সন প্রক্রিয়ায় বাইরের লাইব্রেরি ব্যবহার করতে পারেন, যেমন ডেটা ফরম্যাট কনভার্শন লাইব্রেরি।

সারাংশ

Custom Mapping MapStruct এর একটি অত্যন্ত গুরুত্বপূর্ণ বৈশিষ্ট্য, যা আপনাকে আপনার প্রোজেক্টের ম্যাপিং প্রক্রিয়ায় কাস্টম লজিক এবং কনভার্সন প্রয়োগ করতে সহায়তা করে। যখন ডোমেইন অবজেক্ট এবং DTO এর মধ্যে সরাসরি ম্যাপিং সম্ভব হয় না বা একটি বিশেষ ট্রান্সফরমেশন প্রয়োজন হয়, তখন Custom Mapping ব্যবহৃত হয়। MapStruct কাস্টম মেথড এবং @Mapping অ্যানোটেশন ব্যবহার করে এসব কাস্টম লজিক সহজেই প্রয়োগ করা যায়, যা ডেটা এক্সচেঞ্জ এবং ট্রান্সফরমেশনকে আরো কার্যকরী এবং স্বচ্ছ করে তোলে।


Content added By

MapStruct এর মাধ্যমে Custom Type Conversion করা

223

MapStruct একটি শক্তিশালী Java মডেল ম্যাপিং টুল যা ডোমেইন অবজেক্ট এবং DTO (Data Transfer Object) এর মধ্যে দ্রুত এবং সঠিকভাবে ডেটা ম্যাপিং সম্পন্ন করতে সহায়তা করে। এটি মূলত compile-time এ কোড জেনারেট করে এবং রানটাইমে অতিরিক্ত প্রসেসিং বা রিফ্লেকশন ব্যবহার না করে পারফরম্যান্সে সহায়তা করে। Custom Type Conversion হল MapStruct এর একটি গুরুত্বপূর্ণ বৈশিষ্ট্য, যা আপনি যখন ডোমেইন অবজেক্ট এবং DTO এর মধ্যে ম্যাপিং করতে চান এবং বিশেষ কাস্টম কনভার্সন লজিক প্রয়োগ করতে চান তখন ব্যবহৃত হয়।

Custom Type Conversion প্রয়োজন হয় যখন আপনি কোন নির্দিষ্ট প্রপার্টির মধ্যে কাস্টম কনভার্টার বা লজিক প্রয়োগ করতে চান, যেমন ডেটা ফরম্যাট কনভার্ট করা বা এনামের (enum) মান ট্রান্সফর্ম করা।


১. Custom Type Conversion এর প্রয়োজনীয়তা

Custom Type Conversion এর প্রয়োজনীয়তা তখনই ঘটে যখন MapStruct এর ডিফল্ট ম্যাপিং লজিক আপনার প্রয়োজন অনুযায়ী কাজ না করে। কিছু উদাহরণ দেওয়া হল যেখানে কাস্টম টাইপ কনভার্সন প্রয়োজন হতে পারে:

  • String to Date Conversion: যদি আপনি একটি String ফিল্ডকে Date ফিল্ডে কনভার্ট করতে চান।
  • Enum to String Conversion: যদি একটি Enum মানকে String এ রূপান্তর করতে চান।
  • Complex Object Mapping: যদি আপনার অবজেক্টে কিছু কাস্টম কনভার্সন লজিক (যেমন গণনা, ফিল্ডের রূপান্তর) প্রয়োজন হয়।
  • Custom Date Format: যদি ডেটার ফরম্যাট কনভার্ট করতে হয়, যেমন yyyy-MM-dd থেকে MM/dd/yyyy

২. Custom Type Conversion উদাহরণ

এখানে একটি উদাহরণ দেওয়া হয়েছে যেখানে আমরা String থেকে Date কনভার্ট করব এবং একটি Enum মানকে String এ কনভার্ট করব।

২.১ String to Date Conversion

ধরা যাক আমাদের একটি EmployeeDTO অবজেক্ট আছে যেখানে dateOfBirth একটি String হিসেবে থাকবে, এবং আমরা এটি Date এ কনভার্ট করতে চাই।

EmployeeDTO.java
public class EmployeeDTO {
    private String name;
    private String dateOfBirth; // String type
    private Date dateOfBirthConverted; // Date type

    // Getters and Setters
}

এখন, আমরা String থেকে Date কনভার্ট করার জন্য একটি কাস্টম কনভার্সন তৈরি করব।

EmployeeMapper.java
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.text.SimpleDateFormat;
import java.util.Date;

@Mapper
public interface EmployeeMapper {
    EmployeeMapper INSTANCE = Mappers.getMapper(EmployeeMapper.class);

    @Mapping(source = "dateOfBirth", target = "dateOfBirthConverted", dateFormat = "yyyy-MM-dd")
    EmployeeDTO employeeToEmployeeDTO(Employee employee);

    // Custom method for String to Date conversion
    default Date stringToDate(String date) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.parse(date);
        } catch (Exception e) {
            return null;  // Handle error or return default value
        }
    }
}

এখানে, stringToDate মেথডটি একটি কাস্টম কনভার্টার হিসেবে কাজ করছে যা String ফরম্যাট yyyy-MM-dd থেকে Date ফরম্যাটে কনভার্ট করবে।


২.২ Enum to String Conversion

এখন, ধরুন আমাদের একটি GenderEnum রয়েছে এবং আমরা এই Enum থেকে String এ কনভার্ট করতে চাই।

GenderEnum.java
public enum GenderEnum {
    MALE, FEMALE, OTHER;
}
EmployeeDTO.java (এনামের মান String এ কনভার্ট করার জন্য)
public class EmployeeDTO {
    private String name;
    private String gender; // String type to represent the Enum

    // Getters and Setters
}
EmployeeMapper.java (কাস্টম এনাম কনভার্টার)
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper
public interface EmployeeMapper {
    EmployeeMapper INSTANCE = Mappers.getMapper(EmployeeMapper.class);

    @Mapping(source = "gender", target = "gender")
    EmployeeDTO employeeToEmployeeDTO(Employee employee);

    // Custom method to convert Enum to String
    default String genderToString(GenderEnum gender) {
        if (gender != null) {
            return gender.name();
        } else {
            return null;  // Or return default value
        }
    }
}

এখানে, genderToString মেথডটি GenderEnum এর মানকে String এ কনভার্ট করার জন্য ব্যবহার হচ্ছে।


৩. Custom Type Conversion এর উপকারিতা

  • কাস্টম কনভার্সন ব্যবহারের মাধ্যমে আপনি complex transformation সম্পাদন করতে পারেন যা ডিফল্ট MapStruct ম্যাপিংয়ের বাইরে যায়।
  • এটি null checking এবং error handling সহজ করে তোলে, কারণ আপনি কাস্টম লজিক ব্যবহার করে null ভ্যালু বা ভুল ফরম্যাট হ্যান্ডেল করতে পারবেন।
  • স্ট্রিং থেকে ডেটা কনভার্ট, এনাম থেকে স্ট্রিং কনভার্ট, বা কমপ্লেক্স অবজেক্ট ম্যাপিং এর ক্ষেত্রে এটি অত্যন্ত উপকারী।

৪. MapStruct এর সাথে Custom Type Conversion ব্যবহারের জন্য নির্দেশনা

  1. Default Methods: MapStruct আপনাকে default methods ব্যবহার করার মাধ্যমে কাস্টম কনভার্সন তৈরি করতে দেয়, যা সরাসরি Mapper ইন্টারফেসে যুক্ত করা যায়।
  2. MapStruct Integration: এটি সহজেই Spring, Quarkus, JPA ইত্যাদির সাথে ইন্টিগ্রেট করা যায়।
  3. Error Handling: কাস্টম কনভার্টারে সঠিক ত্রুটি সন্নিবেশিত করা যায় যাতে কোনো ভুল ইনপুট ডেটা আসলে তা সঠিকভাবে হ্যান্ডেল করা যায়।
  4. Reusable Conversion Methods: কাস্টম কনভার্টারগুলো আপনি বিভিন্ন Mapper এ ব্যবহার করতে পারেন, যা কোডের পুনরাবৃত্তি কমায়।

সারাংশ

MapStruct এর মাধ্যমে Custom Type Conversion করা অত্যন্ত সহজ এবং কার্যকরী। আপনি কাস্টম কনভার্সন মেথড ব্যবহার করে String to Date, Enum to String এবং অন্যান্য কাস্টম ট্রান্সফরমেশন কাজ করতে পারেন। এতে MapStruct এর সাধারণ ম্যাপিং লজিকের বাইরে বিশেষ কনভার্সন প্রয়োগ করা যায়, যা আপনার প্রোজেক্টে ডেটা প্রক্রিয়াকে আরও কার্যকরী ও সঠিক করে তোলে।


Content added By

String, Date, এবং Custom Object এর মধ্যে Conversion

251

MapStruct একটি জনপ্রিয় Java annotation processor যা compile-time এ কোড জেনারেট করে। এটি সাধারণত model mapping বা object mapping জন্য ব্যবহৃত হয়, যেখানে আপনি একটি অবজেক্টের ডেটা অন্য একটি অবজেক্টে ট্রান্সফার করতে চান। তবে, কিছু ক্ষেত্রে custom conversion প্রক্রিয়ার প্রয়োজন হয়, যেমন String to Date, Date to String, এবং Custom Object to Another Custom Object ম্যাপিং।

এই টিউটোরিয়ালে, আমরা দেখব কিভাবে MapStruct ব্যবহার করে String, Date, এবং Custom Object এর মধ্যে কনভার্সন করা যায়।


১. String এবং Date এর মধ্যে Conversion

একটি সাধারণ কনভার্সন যা অনেকসময় প্রয়োজন হয় তা হলো String থেকে Date এবং Date থেকে String কনভার্সন। এর জন্য MapStruct কাস্টম মেথড ব্যবহার করে কনভার্সন কার্য সম্পন্ন করতে সহায়তা করে।

উদাহরণ: String to Date Conversion

ধরা যাক, আমাদের একটি String আছে যেটি একটি নির্দিষ্ট ফরম্যাটে আছে এবং আমরা সেটি Date অবজেক্টে কনভার্ট করতে চাই।

Custom Mapper Interface:
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import java.text.SimpleDateFormat;
import java.util.Date;

@Mapper
public interface CustomMapper {
    CustomMapper INSTANCE = Mappers.getMapper(CustomMapper.class);

    // String to Date conversion
    @Mapping(target = "dateOfBirth", expression = "java(stringToDate(person.getDateOfBirth()))")
    PersonDTO personToPersonDTO(Person person);

    // String to Date conversion method
    default Date stringToDate(String date) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.parse(date);
        } catch (Exception e) {
            return null;
        }
    }
}

এখানে, stringToDate মেথডটি String কে Date এ কনভার্ট করছে। MapStruct এর মাধ্যমে personToPersonDTO মেথডে String ফিল্ডের মান Date এ কনভার্ট হয়ে যাবে।

Person.java (Source Object):
public class Person {
    private String name;
    private String dateOfBirth; // yyyy-MM-dd

    // Getters and Setters
}
PersonDTO.java (Target Object):
public class PersonDTO {
    private String name;
    private Date dateOfBirth;

    // Getters and Setters
}

Conversion Output:

MapStruct এর মাধ্যমে এই ম্যাপিং সম্পন্ন হলে, dateOfBirth ফিল্ডটি String থেকে Date এ কনভার্ট হবে।


২. Date to String Conversion

আমরা পূর্বের উদাহরণে String to Date কনভার্ট করেছি, তবে অনেক সময় প্রয়োজন হয় Date কে String এ কনভার্ট করার। এটি করার জন্যও আপনি MapStruct এর মাধ্যমে কাস্টম কনভার্সন মেথড তৈরি করতে পারেন।

উদাহরণ: Date to String Conversion

Custom Mapper Interface:
@Mapper
public interface CustomMapper {
    CustomMapper INSTANCE = Mappers.getMapper(CustomMapper.class);

    @Mapping(target = "dateOfBirth", expression = "java(dateToString(personDTO.getDateOfBirth()))")
    PersonDTO personToPersonDTO(Person person);

    // Date to String conversion method
    default String dateToString(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }
}

এখানে, dateToString মেথডটি Date কে String এ কনভার্ট করে, এবং MapStruct এটি স্বয়ংক্রিয়ভাবে ম্যাপিংয়ের সময় ব্যবহার করবে।

Person.java (Source Object):
public class Person {
    private String name;
    private Date dateOfBirth;

    // Getters and Setters
}
PersonDTO.java (Target Object):
public class PersonDTO {
    private String name;
    private String dateOfBirth; // yyyy-MM-dd

    // Getters and Setters
}

Conversion Output:

এখানে dateOfBirth ফিল্ডটি Date থেকে String এ কনভার্ট হয়ে যাবে।


৩. Custom Object এর মধ্যে Conversion

MapStruct কাস্টম অবজেক্টের মধ্যে ম্যাপিং করার জন্য কাস্টম কনভার্সন মেথড ব্যবহার করতে দেয়। অনেক সময় আপনার নিজের তৈরি করা অবজেক্টের মধ্যে কনভার্সন প্রয়োজন হতে পারে, যেখানে ডেটা কাস্টম ফরম্যাটে থাকতে পারে।

উদাহরণ: Custom Object Mapping

ধরা যাক, আমাদের একটি Person অবজেক্ট আছে এবং আমরা সেটিকে একটি PersonDTO তে ম্যাপ করতে চাই, যেখানে address এবং contact ফিল্ডের কাস্টম ম্যাপিং প্রয়োজন।

Person.java (Source Object):
public class Person {
    private String name;
    private Address address;
    private Contact contact;

    // Getters and Setters
}
Address.java (Custom Object):
public class Address {
    private String city;
    private String state;

    // Getters and Setters
}
Contact.java (Custom Object):
public class Contact {
    private String phone;
    private String email;

    // Getters and Setters
}
PersonDTO.java (Target Object):
public class PersonDTO {
    private String name;
    private String address;
    private String contactDetails;

    // Getters and Setters
}
CustomMapper.java (Custom Mapper Interface):
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper
public interface CustomMapper {
    CustomMapper INSTANCE = Mappers.getMapper(CustomMapper.class);

    @Mapping(target = "address", expression = "java(mapAddressToString(person.getAddress()))")
    @Mapping(target = "contactDetails", expression = "java(mapContactToString(person.getContact()))")
    PersonDTO personToPersonDTO(Person person);

    // Address to String conversion
    default String mapAddressToString(Address address) {
        return address.getCity() + ", " + address.getState();
    }

    // Contact to String conversion
    default String mapContactToString(Contact contact) {
        return contact.getPhone() + ", " + contact.getEmail();
    }
}

এখানে:

  • mapAddressToString: Address অবজেক্টের ফিল্ডগুলিকে একটি String এ কনভার্ট করছে।
  • mapContactToString: Contact অবজেক্টের ফিল্ডগুলিকে একটি String এ কনভার্ট করছে।

Conversion Output:

এই কাস্টম ম্যাপিংয়ের মাধ্যমে, Person অবজেক্টের address এবং contact ফিল্ডের মান কাস্টম কনভার্ট হয়ে PersonDTO তে String হিসেবে আসবে।


৪. Null Handling in Conversion

MapStruct আপনাকে null মানগুলির জন্য কাস্টম লজিক যোগ করার সুবিধা দেয়। আপনি null check কাস্টম মেথডে অন্তর্ভুক্ত করতে পারেন যাতে অ্যাপ্লিকেশনে null pointer exceptions প্রতিরোধ করা যায়।

Example with Null Check

@Mapper
public interface CustomMapper {
    CustomMapper INSTANCE = Mappers.getMapper(CustomMapper.class);

    @Mapping(target = "address", expression = "java(mapAddressToString(person.getAddress()))")
    PersonDTO personToPersonDTO(Person person);

    // Null check with custom mapping
    default String mapAddressToString(Address address) {
        if (address == null) {
            return "Unknown Address";
        }
        return address.getCity() + ", " + address.getState();
    }
}

এখানে, mapAddressToString মেথডটি null চেক করেছে এবং যদি Address অবজেক্টটি null হয় তবে "Unknown Address" রিটার্ন করবে।


সারাংশ

MapStruct ব্যবহার করে String, Date, এবং Custom Object এর মধ্যে কনভার্সন খুবই সহজ। এটি কাস্টম কনভার্সন লজিক যোগ করার জন্য কাস্টম ম্যাপিং মেথডের সুবিধা প্রদান করে, এবং null হ্যান্ডলিং সহ এটি আপনার কোডের কার্যকারিতা এবং স্থায়িত্ব বৃদ্ধি করে। MapStruct আপনাকে compile-time কোড জেনারেশন সুবিধা প্রদান করে, যা আপনার অ্যাপ্লিকেশন পারফরম্যান্সে ইতিবাচক প্রভাব ফেলে।


Content added By

উদাহরণ সহ Custom Mapping এবং Conversion

274

MapStruct একটি শক্তিশালী টুল যা Java Beans (POJOs) এর মধ্যে অটোমেটিক ম্যাপিং এবং কাস্টম কনভার্শন পরিচালনা করতে সক্ষম। কখনও কখনও, ডিফল্ট ম্যাপিং থেকে বেশি কাস্টমাইজেশন প্রয়োজন হয়, যেমন বিশেষ ধরনের ডেটা কনভার্সন বা ভিন্ন ফরম্যাটে ডেটা এক্সচেঞ্জ। এই ক্ষেত্রে MapStruct আপনাকে Custom Mapping এবং Conversion এর সুযোগ প্রদান করে।

এখানে, আমরা MapStruct ব্যবহার করে String, Date, এবং Custom Object এর মধ্যে কাস্টম কনভার্শন কিভাবে করা যায় তা উদাহরণের মাধ্যমে দেখাবো।


১. MapStruct Custom Mapping এবং Conversion Overview

Custom Mapping এর প্রয়োজনীয়তা তখনই হয় যখন আপনি ডিফল্ট ম্যাপিং থেকে আলাদা কোনো ট্রান্সফরমেশন বা কনভার্শন করতে চান। MapStruct আপনাকে কাস্টম Mapping Methods এবং Conversion Methods তৈরি করার সুবিধা দেয়, যা বিশেষভাবে String, Date, এবং Custom Object এর মধ্যে ডেটা কনভার্ট করতে ব্যবহৃত হয়।


২. String এবং Date এর মধ্যে Conversion

ধরা যাক, আপনি একটি String এবং Date ফরম্যাটের মধ্যে কনভার্শন করতে চান, যেমন একটি String ডেটাতে রূপান্তর বা একটি Date অবজেক্টকে একটি নির্দিষ্ট স্ট্রিং ফরম্যাটে রূপান্তর করা।

উদাহরণ: String এবং Date এর মধ্যে Conversion

Employee.java (Domain Object)
import java.util.Date;

public class Employee {
    private String name;
    private Date joiningDate;

    // Getters and Setters
}
EmployeeDTO.java (DTO)
public class EmployeeDTO {
    private String name;
    private String joiningDateString;

    // Getters and Setters
}

Custom Mapping with MapStruct

এখন, আমরা একটি কাস্টম ম্যাপিং মেথড তৈরি করব যা Date থেকে String এবং String থেকে Date কনভার্ট করবে।

EmployeeMapper.java (Mapper Interface)
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import java.text.SimpleDateFormat;
import java.util.Date;

@Mapper
public interface EmployeeMapper {
    EmployeeMapper INSTANCE = Mappers.getMapper(EmployeeMapper.class);

    // Mapping from Employee to EmployeeDTO
    @Mapping(source = "joiningDate", target = "joiningDateString", dateFormat = "dd-MM-yyyy")
    EmployeeDTO employeeToEmployeeDTO(Employee employee);

    // Custom Mapping from String to Date
    default Date stringToDate(String dateStr) {
        try {
            return new SimpleDateFormat("dd-MM-yyyy").parse(dateStr);
        } catch (Exception e) {
            return null;
        }
    }

    // Custom Mapping from Date to String
    default String dateToString(Date date) {
        return new SimpleDateFormat("dd-MM-yyyy").format(date);
    }
}

এখানে:

  • @Mapping অ্যানোটেশন ব্যবহার করা হয়েছে, যাতে Date অবজেক্টটি String ফরম্যাটে কনভার্ট করা হয় এবং এটি joiningDateString ফিল্ডে ম্যাপ করা হয়।
  • কাস্টম stringToDate এবং dateToString মেথড তৈরি করা হয়েছে, যেগুলি স্ট্রিং এবং ডেটার মধ্যে কনভার্সন করবে।

Main.java (Usage Example)

import java.util.Date;

public class Main {
    public static void main(String[] args) {
        Employee employee = new Employee();
        employee.setName("John Doe");
        employee.setJoiningDate(new Date());

        // Mapping
        EmployeeDTO employeeDTO = EmployeeMapper.INSTANCE.employeeToEmployeeDTO(employee);
        System.out.println("Name: " + employeeDTO.getName());
        System.out.println("Joining Date: " + employeeDTO.getJoiningDateString());
    }
}

এখানে, employeeToEmployeeDTO মেথডটি Date অবজেক্টকে String এ কনভার্ট করবে এবং সঠিক ফরম্যাটে প্রিন্ট করবে।


৩. Custom Object Conversion

কখনও কখনও আপনাকে একাধিক কাস্টম অবজেক্টের মধ্যে ম্যাপিং করতে হতে পারে, যেমন একটি কাস্টম ক্লাসের ফিল্ড থেকে অন্য একটি কাস্টম ক্লাসের ফিল্ডে মান ম্যাপ করা।

উদাহরণ: Custom Object Conversion

Address.java (Domain Object)
public class Address {
    private String street;
    private String city;

    // Getters and Setters
}
AddressDTO.java (DTO)
public class AddressDTO {
    private String streetName;
    private String cityName;

    // Getters and Setters
}

Custom Object Mapping with MapStruct

এখন, আমরা একটি কাস্টম ম্যাপিং মেথড তৈরি করব যা Address থেকে AddressDTO তে কাস্টম ফিল্ড ম্যাপিং করবে।

AddressMapper.java (Mapper Interface)
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper
public interface AddressMapper {
    AddressMapper INSTANCE = Mappers.getMapper(AddressMapper.class);

    @Mapping(source = "street", target = "streetName")
    @Mapping(source = "city", target = "cityName")
    AddressDTO addressToAddressDTO(Address address);
}

এখানে, street ফিল্ডটি streetName ফিল্ডে এবং city ফিল্ডটি cityName ফিল্ডে ম্যাপ করা হয়েছে।

Main.java (Usage Example)

public class Main {
    public static void main(String[] args) {
        Address address = new Address();
        address.setStreet("123 Main St");
        address.setCity("New York");

        // Mapping
        AddressDTO addressDTO = AddressMapper.INSTANCE.addressToAddressDTO(address);
        System.out.println("Street: " + addressDTO.getStreetName());
        System.out.println("City: " + addressDTO.getCityName());
    }
}

এখানে, addressToAddressDTO মেথডটি Address অবজেক্টের ফিল্ডগুলোকে AddressDTO তে কাস্টম ভাবে ম্যাপ করবে।


৪. MapStruct এর মাধ্যমে Custom Conversion এর সুবিধা

  1. Flexible Mapping: কাস্টম ম্যাপিংয়ের মাধ্যমে আপনি যেকোনো ধরনের কাস্টম লজিক প্রয়োগ করতে পারেন, যেমন ডেটা ট্রান্সফরমেশন, এনাম কনভার্শন বা স্পেশাল ফরম্যাটিং।
  2. Code Generation: MapStruct compile-time এ কোড জেনারেট করে, তাই এর কোনো রানটাইম পারফরম্যান্স ইস্যু নেই।
  3. Error Handling: আপনি কাস্টম কনভার্সন মেথডে null চেক এবং অন্যান্য ত্রুটি সমাধান যুক্ত করতে পারেন।

সারাংশ

MapStruct এর মাধ্যমে আপনি String, Date, এবং Custom Object এর মধ্যে কাস্টম কনভার্সন এবং ম্যাপিং সহজে করতে পারেন। কাস্টম ম্যাপিংয়ের মাধ্যমে আপনি আপনার প্রোজেক্টে নির্দিষ্ট ডেটা ট্রান্সফরমেশন এবং কাস্টম লজিক প্রয়োগ করতে পারবেন। MapStruct এর কোড জেনারেশন ক্ষমতা, টাইপ সেফটি, এবং পারফরম্যান্স নিশ্চিতকরণ এর প্রধান সুবিধা, যা ম্যাপিং প্রক্রিয়াকে দ্রুত এবং কার্যকরী করে তোলে।


Content added By
Promotion

Are you sure to start over?

Loading...