MapStruct একটি শক্তিশালী মডেল মেপিং টুল যা JavaBeans (POJOs) বা ডোমেইন অবজেক্টগুলির মধ্যে ম্যাপিং করতে ব্যবহৃত হয়। যখন আপনার অবজেক্টে nested objects থাকে, তখন MapStruct সহজেই এই nested objects এর মধ্যে ম্যাপিং করতে পারে। Nested Object Mapping MapStruct এর একটি গুরুত্বপূর্ণ ফিচার, যা ডেটা ট্রান্সফার এবং কোডের সজ্জা সহজ এবং দ্রুত করে তোলে। এটি মূলত একটি অবজেক্টের মধ্যে অন্য অবজেক্টকে ম্যাপ করার কাজ করে।
এই টিউটোরিয়ালে আমরা MapStruct Nested Object Mapping এর উদাহরণ সহ দেখব।
Nested Object Mapping হল একটি প্রক্রিয়া যেখানে একটি অবজেক্টের একটি প্রোপার্টি অন্য একটি অবজেক্ট হয় এবং সেই অবজেক্টের ফিল্ডগুলিও ম্যাপ করতে হয়। এটি এমনকি গভীর (deep) অবজেক্ট স্ট্রাকচারেও কার্যকরভাবে কাজ করে। MapStruct এর মাধ্যমে আপনি সহজেই এই ধরনের ম্যাপিং করতে পারেন।
ধরা যাক, আমাদের দুটি ক্লাস রয়েছে: Employee এবং Address, যেখানে Employee ক্লাসের মধ্যে Address নামে একটি nested object রয়েছে। আমরা Employee অবজেক্ট থেকে EmployeeDTO অবজেক্টে ম্যাপিং করতে চাই, যেখানে Address এর মধ্যে থাকা ফিল্ডগুলি AddressDTO তে ম্যাপ হবে।
public class Employee {
private String name;
private int age;
private Address address; // Nested object
// Getters and Setters
}
public class Address {
private String street;
private String city;
// Getters and Setters
}
public class EmployeeDTO {
private String name;
private int age;
private AddressDTO addressDTO; // Nested DTO
// Getters and Setters
}
public class AddressDTO {
private String street;
private String city;
// Getters and Setters
}
এখন, Employee এবং Address অবজেক্টের মধ্যে ম্যাপিং করতে হবে, যেখানে Employee অবজেক্টের address ফিল্ডটি AddressDTO তে ম্যাপ হবে।
MapStruct ব্যবহার করে আমরা EmployeeMapper ইন্টারফেস তৈরি করব, যা Employee থেকে EmployeeDTO তে এবং Address থেকে AddressDTO তে ম্যাপিং করবে।
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 = "address", target = "addressDTO") // Nested object mapping
EmployeeDTO employeeToEmployeeDTO(Employee employee);
}
এখানে, @Mapping অ্যানোটেশনটি ব্যবহার করে Employee অবজেক্টের address ফিল্ডটি EmployeeDTO তে addressDTO নামক ফিল্ডে ম্যাপ করা হচ্ছে। MapStruct স্বয়ংক্রিয়ভাবে Address থেকে AddressDTO তে ম্যাপিং পরিচালনা করবে।
এখন, আমরা একটি Main ক্লাস তৈরি করব যা Employee অবজেক্ট তৈরি করবে এবং তারপর EmployeeMapper ব্যবহার করে এটি EmployeeDTO তে ম্যাপ করবে।
public class Main {
public static void main(String[] args) {
// Creating Address object
Address address = new Address();
address.setStreet("123 Main St");
address.setCity("New York");
// Creating Employee object
Employee employee = new Employee();
employee.setName("John Doe");
employee.setAge(30);
employee.setAddress(address);
// Mapping Employee to EmployeeDTO
EmployeeDTO employeeDTO = EmployeeMapper.INSTANCE.employeeToEmployeeDTO(employee);
// Output the results
System.out.println("Employee Name: " + employeeDTO.getName());
System.out.println("Employee Age: " + employeeDTO.getAge());
System.out.println("Employee Address: " + employeeDTO.getAddressDTO().getStreet() + ", " + employeeDTO.getAddressDTO().getCity());
}
}
Employee Name: John Doe
Employee Age: 30
Employee Address: 123 Main St, New York
এখানে, Employee অবজেক্টের address ফিল্ড EmployeeDTO এর addressDTO তে সফলভাবে ম্যাপ হয়েছে।
যখন আপনার nested objects আরও গভীর হয়, যেমন একটি Address অবজেক্টের মধ্যে City অবজেক্ট থাকে, MapStruct স্বয়ংক্রিয়ভাবে গভীর ম্যাপিংও পরিচালনা করতে সক্ষম। আপনাকে শুধু উপযুক্ত Mapper ইন্টারফেস তৈরি করতে হবে।
ধরা যাক, আমাদের Address অবজেক্টের মধ্যে City নামক একটি nested object রয়েছে।
public class City {
private String name;
private String zipCode;
// Getters and Setters
}
এখন, Address ক্লাসে City অবজেক্ট হবে:
public class Address {
private String street;
private String city; // Here city is now an object
// Getters and Setters
}
MapStruct এই ধরনের ডিপ নেস্টেড অবজেক্টগুলির মধ্যে ডেটা ম্যাপিং করবে, যদি আপনি Mapper কনফিগার করেন।
MapStruct সহজেই nested object mapping পরিচালনা করতে পারে, যা ডেটা ট্রান্সফার এবং কোডের গঠন সহজ করে তোলে। এটি @Mapping অ্যানোটেশন ব্যবহার করে, যেখানে আপনি এক অবজেক্টের ফিল্ড অন্য অবজেক্টে ম্যাপ করতে পারেন। আপনি যখন nested objects বা গভীর কাঠামোতে ম্যাপিং করতে চান, MapStruct সেগুলিকে দক্ষতার সাথে পরিচালনা করে। এটি compile-time code generation এবং type safety সহ একটি দ্রুত এবং কার্যকরী সমাধান প্রদান করে।
Nested Object Mapping হল এমন একটি প্রক্রিয়া যেখানে একটি অবজেক্টের মধ্যে থাকা একটি বা একাধিক সাব অবজেক্ট (nested objects) এর মধ্যে ডেটা ম্যাপিং করা হয়। MapStruct এর মাধ্যমে, আপনি nested অবজেক্টগুলির মধ্যে ডেটা ট্রান্সফার বা ম্যাপিং খুব সহজে করতে পারেন। MapStruct এই প্রক্রিয়াটি compile-time code generation এর মাধ্যমে সম্পন্ন করে, ফলে এটি দ্রুত এবং পারফর্ম্যান্সে দক্ষ হয়।
এখানে, Nested Object Mapping এর ধারণা ব্যাখ্যা করা হবে এবং উদাহরণসহ কিভাবে এটি MapStruct এর মাধ্যমে করা যায়, তা দেখানো হবে।
Nested Object Mapping এর মাধ্যমে, আপনি একটি অবজেক্টের মধ্যে থাকা একাধিক সাব অবজেক্ট (যা একটি ডোমেইন অবজেক্ট হতে পারে) এর মধ্যে ডেটা ম্যাপিং করতে পারেন। উদাহরণস্বরূপ, ধরুন আপনার একটি Customer ক্লাস রয়েছে, যার মধ্যে একটি Address নামক সাব অবজেক্ট রয়েছে। আপনি যদি Customer থেকে CustomerDTO তে ডেটা ম্যাপ করতে চান এবং সাথে Address অবজেক্টের মানও ম্যাপ করতে চান, তাহলে এটি Nested Object Mapping হিসেবে পরিচিত।
ধরা যাক, আমাদের দুটি ক্লাস রয়েছে: Customer এবং Address। আমাদের Customer অবজেক্ট থেকে CustomerDTO তে ডেটা ম্যাপ করতে হবে, এবং Address সাব অবজেক্টটিও ম্যাপ করতে হবে।
Customer.java:
public class Customer {
private String name;
private Address address;
// Getters and Setters
}
Address.java:
public class Address {
private String city;
private String street;
// Getters and Setters
}
CustomerDTO.java:
public class CustomerDTO {
private String name;
private String city;
private String street;
// Getters and Setters
}
এখানে, Customer ক্লাসের মধ্যে একটি Address অবজেক্ট রয়েছে, এবং CustomerDTO তে Address এর city
এবং street
মান ম্যাপ করতে হবে।
এখন, MapStruct ব্যবহার করে আমরা একটি Mapper Interface তৈরি করব, যা Customer থেকে CustomerDTO তে ডেটা ম্যাপ করবে।
CustomerMapper.java:
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface CustomerMapper {
CustomerMapper INSTANCE = Mappers.getMapper(CustomerMapper.class);
// Mapping method for Customer to CustomerDTO
@Mapping(source = "address.city", target = "city")
@Mapping(source = "address.street", target = "street")
CustomerDTO customerToCustomerDTO(Customer customer);
}
এখানে, @Mapping
অ্যানোটেশন ব্যবহার করা হয়েছে, যা Address এর city
এবং street
প্রপার্টি CustomerDTO এর city
এবং street
প্রপার্টিতে ম্যাপ করবে।
এখন, CustomerMapper ব্যবহার করে Customer অবজেক্টের ডেটা CustomerDTO তে ম্যাপ করা হবে।
Main.java:
public class Main {
public static void main(String[] args) {
// Create Customer object with Address
Address address = new Address();
address.setCity("Dhaka");
address.setStreet("Gulshan");
Customer customer = new Customer();
customer.setName("John Doe");
customer.setAddress(address);
// Map Customer to CustomerDTO
CustomerDTO customerDTO = CustomerMapper.INSTANCE.customerToCustomerDTO(customer);
System.out.println("Customer Name: " + customerDTO.getName());
System.out.println("Customer City: " + customerDTO.getCity());
System.out.println("Customer Street: " + customerDTO.getStreet());
}
}
এখানে, CustomerMapper.INSTANCE.customerToCustomerDTO(customer) মাধ্যমে Customer অবজেক্ট থেকে CustomerDTO তে ডেটা ম্যাপ করা হয়েছে। Address এর city
এবং street
ডেটাও সঠিকভাবে ম্যাপ করা হয়েছে।
city
এর মান addressCity
এ ম্যাপ করতে চাইলে কাস্টম ম্যাপিং ব্যবহার করতে পারবেন।ধরা যাক, আমাদের একটি Company ক্লাস রয়েছে, যার মধ্যে একাধিক Employee অবজেক্ট রয়েছে এবং তাদের Address সাব অবজেক্ট রয়েছে। এখানে Company থেকে CompanyDTO তে ডেটা ম্যাপ করতে হবে।
Company.java:
import java.util.List;
public class Company {
private String name;
private List<Employee> employees;
// Getters and Setters
}
Employee.java:
public class Employee {
private String name;
private Address address;
// Getters and Setters
}
Address.java:
public class Address {
private String city;
private String street;
// Getters and Setters
}
CompanyDTO.java:
import java.util.List;
public class CompanyDTO {
private String companyName;
private List<EmployeeDTO> employees;
// Getters and Setters
}
EmployeeDTO.java:
public class EmployeeDTO {
private String name;
private String city;
private String street;
// Getters and Setters
}
এখন, Company থেকে CompanyDTO তে ম্যাপিং করতে হলে, Employee এবং Address অবজেক্টের জন্যও ম্যাপিং করতে হবে।
CompanyMapper.java:
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface CompanyMapper {
CompanyMapper INSTANCE = Mappers.getMapper(CompanyMapper.class);
@Mapping(source = "name", target = "companyName")
@Mapping(source = "employees", target = "employees")
CompanyDTO companyToCompanyDTO(Company company);
// Nested mapping for Employee
@Mapping(source = "address.city", target = "city")
@Mapping(source = "address.street", target = "street")
EmployeeDTO employeeToEmployeeDTO(Employee employee);
}
এখানে, আমরা CompanyMapper তৈরি করেছি যাতে Company থেকে CompanyDTO তে এবং Employee থেকে EmployeeDTO তে ডেটা ম্যাপ করা যায়। Employee ক্লাসের মধ্যে Address সাব অবজেক্টের জন্য কাস্টম ম্যাপিং ব্যবহৃত হয়েছে।
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// Create Address
Address address = new Address();
address.setCity("Dhaka");
address.setStreet("Gulshan");
// Create Employee
Employee employee = new Employee();
employee.setName("Alice");
employee.setAddress(address);
// Create Company
Company company = new Company();
company.setName("Tech Corp");
company.setEmployees(Arrays.asList(employee));
// Map Company to CompanyDTO
CompanyDTO companyDTO = CompanyMapper.INSTANCE.companyToCompanyDTO(company);
// Output
System.out.println("Company Name: " + companyDTO.getCompanyName());
companyDTO.getEmployees().forEach(emp -> {
System.out.println("Employee Name: " + emp.getName());
System.out.println("Employee City: " + emp.getCity());
System.out.println("Employee Street: " + emp.getStreet());
});
}
}
এখানে, CompanyMapper.INSTANCE.companyToCompanyDTO(company) এর মাধ্যমে Company থেকে CompanyDTO তে ম্যাপিং করা হয়েছে এবং Employee এবং Address এর ডেটাও সঠিকভাবে ম্যাপ হয়েছে।
Nested Object Mapping MapStruct এর একটি শক্তিশালী ফিচার, যা আপনাকে nested অবজেক্টগুলির মধ্যে ডেটা ট্রান্সফার বা ম্যাপিং করতে সহায়তা করে। MapStruct এর মাধ্যমে সহজে, টাইপ-সেফ এবং পারফরম্যান্স
MapStruct হল একটি শক্তিশালী এবং কার্যকরী Java library যা ডোমেইন অবজেক্ট এবং ডেটা ট্রান্সফার অবজেক্ট (DTO) এর মধ্যে ম্যাপিং করতে ব্যবহৃত হয়। এক্ষেত্রে, Parent-Child Object Mapping হল এমন একটি পরিস্থিতি যেখানে একটি প্যারেন্ট অবজেক্টের মধ্যে থাকা চাইল্ড অবজেক্টের ডেটা ট্রান্সফার করতে হয়। MapStruct এই ধরনের ম্যাপিং সহজেই করতে পারে, যা আপনার কোডের কাঠামো পরিষ্কার এবং কার্যকরী রাখে।
এই টিউটোরিয়ালে, আমরা দেখব কিভাবে MapStruct ব্যবহার করে Parent-Child Object Mapping সম্পন্ন করা যায়।
Parent-Child Object Mapping এমন একটি প্রক্রিয়া যেখানে একটি প্যারেন্ট অবজেক্টের মধ্যে থাকা চাইল্ড অবজেক্টগুলোর ডেটা ম্যাপ করা হয়। উদাহরণস্বরূপ, যদি একটি Employee অবজেক্ট থাকে এবং এর মধ্যে একটি Address অবজেক্ট থাকে, তাহলে Employee থেকে EmployeeDTO তে ম্যাপ করার সময় Address অবজেক্টকেও আলাদাভাবে ম্যাপ করা হবে।
ধরা যাক, আমাদের দুটি ক্লাস রয়েছে: Employee (প্যারেন্ট) এবং Address (চাইল্ড)। আমাদের লক্ষ্য হল Employee অবজেক্টকে EmployeeDTO তে এবং Address অবজেক্টকে AddressDTO তে ম্যাপ করা।
public class Employee {
private String name;
private int age;
private Address address;
// Getters and Setters
}
public class Address {
private String street;
private String city;
// Getters and Setters
}
public class EmployeeDTO {
private String name;
private int age;
private AddressDTO address;
// Getters and Setters
}
public class AddressDTO {
private String street;
private String city;
// Getters and Setters
}
এখন আমরা একটি MapStruct Mapper Interface তৈরি করব যা Employee এবং Address এর মধ্যে ম্যাপিং করবে।
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface EmployeeMapper {
EmployeeMapper INSTANCE = Mappers.getMapper(EmployeeMapper.class);
// Parent to Parent mapping
@Mapping(source = "address", target = "address")
EmployeeDTO employeeToEmployeeDTO(Employee employee);
// Child to Child mapping
AddressDTO addressToAddressDTO(Address address);
}
এখানে:
employeeToEmployeeDTO
মেথডটি Employee অবজেক্টকে EmployeeDTO তে ম্যাপ করে, এবং এতে address নামে একটি চাইল্ড অবজেক্টও রয়েছে, যাকে AddressDTO তে ম্যাপ করা হবে।addressToAddressDTO
মেথডটি Address অবজেক্টকে AddressDTO তে ম্যাপ করবে।এখন, আপনি MapStruct Mapper ব্যবহার করে Employee অবজেক্টকে EmployeeDTO তে এবং তার Address অবজেক্টকে AddressDTO তে ম্যাপ করতে পারবেন।
public class Main {
public static void main(String[] args) {
Address address = new Address();
address.setStreet("123 Main St");
address.setCity("New York");
Employee employee = new Employee();
employee.setName("John Doe");
employee.setAge(30);
employee.setAddress(address);
// Mapping
EmployeeDTO employeeDTO = EmployeeMapper.INSTANCE.employeeToEmployeeDTO(employee);
// Printing the mapped values
System.out.println("Employee Name: " + employeeDTO.getName());
System.out.println("Employee Age: " + employeeDTO.getAge());
System.out.println("Employee Address: " + employeeDTO.getAddress().getStreet());
}
}
এখানে, employeeToEmployeeDTO মেথডটি Employee অবজেক্ট এবং এর Address অবজেক্টকে EmployeeDTO এবং AddressDTO তে ম্যাপ করবে।
Employee Name: John Doe
Employee Age: 30
Employee Address: 123 Main St
MapStruct আপনাকে কাস্টম কনভার্টার বা কাস্টম লজিক প্রয়োগ করার সুযোগ দেয়। যদি আপনি আরও জটিল ম্যাপিং করতে চান, তবে কাস্টম মেথড ব্যবহার করা যেতে পারে।
এটি একটি উদাহরণ যেখানে Employee এবং Address এর মধ্যে কাস্টম লজিক প্রয়োগ করা হয়েছে:
@Mapper
public interface EmployeeMapper {
EmployeeMapper INSTANCE = Mappers.getMapper(EmployeeMapper.class);
@Mapping(target = "address", expression = "java(customAddressMapping(employee.getAddress()))")
EmployeeDTO employeeToEmployeeDTO(Employee employee);
AddressDTO customAddressMapping(Address address);
}
এখানে, customAddressMapping মেথডটি কাস্টম লজিক প্রয়োগ করতে ব্যবহৃত হচ্ছে, যা Address অবজেক্টকে AddressDTO তে ম্যাপ করে।
Parent-Child Object Mapping হল এমন একটি কৌশল যা MapStruct এর মাধ্যমে সহজে সম্পন্ন করা যায়। MapStruct ডোমেইন অবজেক্ট এবং DTO এর মধ্যে ডেটা ট্রান্সফার বা ম্যাপিংয়ের কাজ খুব দ্রুত এবং কার্যকরীভাবে করতে সাহায্য করে, বিশেষত যখন প্যারেন্ট এবং চাইল্ড অবজেক্টের মধ্যে ডেটা ম্যাপ করতে হয়। এটি কোড জেনারেশন এবং টাইপ সেফটি নিশ্চিত করে, যা পারফরম্যান্সে উন্নতি আনে এবং কোডকে পরিষ্কার রাখে।
MapStruct একটি শক্তিশালী টুল যা JavaBeans বা POJOs (Plain Old Java Objects) এর মধ্যে ডেটা ম্যাপিং করতে ব্যবহৃত হয়। Nested Object Mapping হল এমন একটি প্রক্রিয়া যেখানে এক অবজেক্টের মধ্যে অন্য অবজেক্টের ডেটা ম্যাপ করা হয়। MapStruct ব্যবহার করে এটি খুব সহজে এবং পারফরম্যান্সে দক্ষভাবে সম্পন্ন করা যায়।
এখানে, আমরা Nested Object Mapping এর ধারণা এবং উদাহরণ দেখাবো, যেখানে একটি অবজেক্টের মধ্যে আরেকটি অবজেক্ট ম্যাপ করা হবে।
Nested Object Mapping হল এমন একটি ম্যাপিং, যেখানে একটি অবজেক্টের ফিল্ডের মান অন্য একটি অবজেক্টে ম্যাপ করা হয়। উদাহরণস্বরূপ, ধরুন আমাদের একটি Person অবজেক্ট আছে, যেটির মধ্যে একটি Address অবজেক্ট রয়েছে। এই দুটি অবজেক্টের মধ্যে ম্যাপিং করতে MapStruct ব্যবহার করা যায়।
ধরা যাক, আমাদের দুটি অবজেক্ট রয়েছে: Person এবং Address। আমরা PersonDTO তে Person অবজেক্টের Address ম্যাপ করতে চাই।
public class Person {
private String name;
private int age;
private Address address;
// Getters and Setters
}
public class Address {
private String street;
private String city;
// Getters and Setters
}
public class PersonDTO {
private String name;
private int age;
private AddressDTO address;
// Getters and Setters
}
public class AddressDTO {
private String street;
private String city;
// Getters and Setters
}
এখন, আমাদের Person অবজেক্টকে PersonDTO তে ম্যাপ করতে হবে, এবং Address অবজেক্টটিকে AddressDTO তে ম্যাপ করতে হবে।
এখন, MapStruct Mapper Interface তৈরি করে আমরা Person থেকে PersonDTO এবং Address থেকে AddressDTO তে ম্যাপিং করবো। এখানে Address অবজেক্টটি AddressDTO তে ম্যাপ হবে, যা একটি Nested Mapping হবে।
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface PersonMapper {
PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
@Mapping(source = "address", target = "address")
PersonDTO personToPersonDTO(Person person);
@Mapping(source = "street", target = "street")
@Mapping(source = "city", target = "city")
AddressDTO addressToAddressDTO(Address address);
}
এখানে:
source
হিসেবে Person এবং Address এর ফিল্ডগুলি এবং target
হিসেবে PersonDTO এবং AddressDTO এর ফিল্ডগুলির নাম উল্লেখ করা হয়েছে।এখন, আমরা MapStruct Mapper ব্যবহার করে Person অবজেক্ট থেকে PersonDTO তে ম্যাপিং করব।
public class Main {
public static void main(String[] args) {
Address address = new Address();
address.setStreet("123 Main St");
address.setCity("New York");
Person person = new Person();
person.setName("John Doe");
person.setAge(30);
person.setAddress(address);
// Mapping
PersonDTO personDTO = PersonMapper.INSTANCE.personToPersonDTO(person);
// Output
System.out.println("Name: " + personDTO.getName());
System.out.println("Age: " + personDTO.getAge());
System.out.println("Street: " + personDTO.getAddress().getStreet());
System.out.println("City: " + personDTO.getAddress().getCity());
}
}
এখানে:
উপরোক্ত কোডটি রান করলে আপনি নিম্নলিখিত আউটপুট পাবেন:
Name: John Doe
Age: 30
Street: 123 Main St
City: New York
এখানে, Address এর মধ্যে থাকা street এবং city ফিল্ডগুলি AddressDTO তে সফলভাবে ম্যাপ করা হয়েছে, যা PersonDTO তে অন্তর্ভুক্ত হয়েছে।
Nested Object Mapping MapStruct এর অন্যতম গুরুত্বপূর্ণ বৈশিষ্ট্য, যা আপনি সহজে Parent-Child Object বা Nested Object এর মধ্যে ডেটা ম্যাপ করতে পারেন। উদাহরণস্বরূপ, এখানে Person অবজেক্ট এবং তার মধ্যে থাকা Address অবজেক্টটি PersonDTO এবং AddressDTO তে ম্যাপ করা হয়েছে। MapStruct-এর মাধ্যমে আপনি কোড জেনারেশন এবং টাইপ সেফটির সুবিধা পেতে পারেন, এবং এটি আপনাকে কম কোডে দ্রুত ম্যাপিং সম্পাদন করতে সাহায্য করে।
Read more