Spring ORM এ Inheritance Mapping

Java Technologies - স্প্রিং ওআরএম (Spring ORM)
115
115

Java Persistence API (JPA) এবং Hibernate এর মাধ্যমে Spring ORM এ Inheritance Mapping ব্যবহার করে ডাটাবেসের টেবিলগুলোর মধ্যে Java ক্লাসগুলোর উত্তরাধিকার (Inheritance) সম্পর্ক প্রতিষ্ঠা করা যায়। এটি তখনই কার্যকর হয়, যখন বিভিন্ন ক্লাস একটি কমন বৈশিষ্ট্য (common property) শেয়ার করে।


Inheritance Mapping এর কৌশল

Spring ORM এবং Hibernate এ Inheritance Mapping এর জন্য JPA এর কিছু অ্যানোটেশন ব্যবহার করা হয়। Hibernate তিন ধরনের Inheritance Strategy সমর্থন করে:

  1. SINGLE_TABLE: সব ডেরাইভড ক্লাসের ডাটা একটি সিঙ্গেল টেবিলে সংরক্ষিত হয়।
  2. TABLE_PER_CLASS: প্রতিটি ডেরাইভড ক্লাসের জন্য আলাদা টেবিল তৈরি হয়।
  3. JOINED: প্যারেন্ট এবং ডেরাইভড ক্লাসের জন্য আলাদা টেবিল তৈরি হয়, এবং টেবিলগুলোর মধ্যে JOIN ব্যবহৃত হয়।

Maven ডিপেনডেন্সি

Spring ORM এবং Hibernate ব্যবহার করতে নিম্নোক্ত ডিপেনডেন্সিগুলো যোগ করুন:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.5.4</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.26</version>
</dependency>

SINGLE_TABLE Strategy উদাহরণ

Entity Class তৈরি করা

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "vehicle_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Vehicle {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "name")
    private String name;

    // Getters and Setters
}

@Entity
@DiscriminatorValue("Car")
public class Car extends Vehicle {
    @Column(name = "seating_capacity")
    private int seatingCapacity;

    // Getters and Setters
}

@Entity
@DiscriminatorValue("Bike")
public class Bike extends Vehicle {
    @Column(name = "engine_capacity")
    private int engineCapacity;

    // Getters and Setters
}

TABLE_PER_CLASS Strategy উদাহরণ

Entity Class তৈরি করা

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Vehicle {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "name")
    private String name;

    // Getters and Setters
}

@Entity
public class Car extends Vehicle {
    @Column(name = "seating_capacity")
    private int seatingCapacity;

    // Getters and Setters
}

@Entity
public class Bike extends Vehicle {
    @Column(name = "engine_capacity")
    private int engineCapacity;

    // Getters and Setters
}

JOINED Strategy উদাহরণ

Entity Class তৈরি করা

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Vehicle {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "name")
    private String name;

    // Getters and Setters
}

@Entity
public class Car extends Vehicle {
    @Column(name = "seating_capacity")
    private int seatingCapacity;

    // Getters and Setters
}

@Entity
public class Bike extends Vehicle {
    @Column(name = "engine_capacity")
    private int engineCapacity;

    // Getters and Setters
}

Repository তৈরি করা

Hibernate এর জন্য JPA রেপোজিটরি ব্যবহার করে সহজেই ডেটা ম্যানেজমেন্ট করা যায়।

@Repository
public interface VehicleRepository extends JpaRepository<Vehicle, Integer> {
}

সার্ভিস লেয়ার তৈরি করা

@Service
public class VehicleService {
    @Autowired
    private VehicleRepository vehicleRepository;

    public void saveVehicle(Vehicle vehicle) {
        vehicleRepository.save(vehicle);
    }

    public List<Vehicle> getAllVehicles() {
        return vehicleRepository.findAll();
    }
}

কন্ট্রোলার লেয়ার তৈরি করা

@RestController
@RequestMapping("/vehicles")
public class VehicleController {
    @Autowired
    private VehicleService vehicleService;

    @PostMapping("/add")
    public String addVehicle(@RequestBody Vehicle vehicle) {
        vehicleService.saveVehicle(vehicle);
        return "Vehicle saved successfully!";
    }

    @GetMapping("/all")
    public List<Vehicle> getAllVehicles() {
        return vehicleService.getAllVehicles();
    }
}

Inheritance Mapping এর সুবিধা

  1. পুনঃব্যবহারযোগ্য কোড: প্যারেন্ট ক্লাসে কমন ফিল্ডগুলো ডিফাইন করে কোড পুনঃব্যবহার করা যায়।
  2. বিভিন্ন স্ট্রাটেজি: ডাটাবেস ডিজাইন অনুযায়ী স্ট্রাটেজি নির্বাচন করার সুযোগ।
  3. ডাটা মডেলিং: বিভিন্ন ধরনের ডেটা মডেলিং প্রয়োজনীয়তার জন্য কার্যকর।

Spring ORM এবং Hibernate এর মাধ্যমে Inheritance Mapping ডাটাবেসের সাথে Object-Oriented ডিজাইনের সম্পর্ক তৈরি করে ডেভেলপমেন্ট সহজ করে তোলে।

Content added By

Inheritance Mapping এর ধারণা এবং প্রয়োগ

66
66

Inheritance Mapping হল Hibernate এবং Spring ORM এ ডেটাবেজ টেবিলের মধ্যে অবজেক্ট-ওরিয়েন্টেড ইনহেরিটেন্সের ধারণা বাস্তবায়নের একটি পদ্ধতি। জাভাতে যেভাবে ক্লাস ইনহেরিট করে সাবক্লাস তৈরি করা হয়, ঠিক সেভাবেই ডেটাবেজ টেবিলেও একই সম্পর্ক ম্যাপ করা যায়।

Hibernate বিভিন্ন কৌশল ব্যবহার করে Inheritance Mapping পরিচালনা করে, যা ডেটাবেজ ডিজাইন এবং পারফরম্যান্সের উপর নির্ভর করে।


Inheritance Mapping এর ধরন

Hibernate তিনটি প্রধান কৌশল সরবরাহ করে Inheritance Mapping এর জন্য:

Single Table Strategy

সব ইনহেরিটেড ক্লাসের জন্য একটি মাত্র টেবিল তৈরি হয়। এটি খুবই সহজ এবং দ্রুত কার্যকর, কিন্তু বড় ডেটাবেজে অতিরিক্ত স্থান নষ্ট করতে পারে।

Table per Class Strategy

প্রত্যেক সাবক্লাসের জন্য আলাদা টেবিল তৈরি হয়। এটি স্পেস ব্যবহারে দক্ষ, তবে কোয়েরি জটিল হতে পারে।

Joined Table Strategy

প্রত্যেক ক্লাসের জন্য আলাদা টেবিল তৈরি হয় এবং তাদের মধ্যে সম্পর্ক বজায় রাখার জন্য জয়েন অপারেশন প্রয়োজন হয়। এটি খুবই নমনীয় কিন্তু ধীরগতির হতে পারে।


উদাহরণ: Inheritance Mapping বাস্তবায়ন

১. Entity ক্লাস তৈরি করা

Base Class (Parent Class)

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public abstract class Employee {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    
    private String name;

    // Getters and Setters
}

বর্ণনা:

  • @Entity: Hibernate এর জন্য এটি একটি Entity ক্লাস হিসেবে ঘোষণা করে।
  • @Inheritance: ইনহেরিটেন্স স্ট্র্যাটেজি নির্ধারণ করে।
  • @DiscriminatorColumn: Discriminator কলাম নির্ধারণ করে যা সাবক্লাস চিহ্নিত করে।

Subclass (Child Class)

@Entity
@DiscriminatorValue("FullTime")
public class FullTimeEmployee extends Employee {
    
    private double salary;

    // Getters and Setters
}
@Entity
@DiscriminatorValue("PartTime")
public class PartTimeEmployee extends Employee {
    
    private double hourlyRate;

    // Getters and Setters
}

বর্ণনা:

  • @DiscriminatorValue: প্রতিটি সাবক্লাসের জন্য আলাদা মান নির্ধারণ করে।
  • FullTimeEmployee এবং PartTimeEmployee মূলত Parent Class (Employee) থেকে ইনহেরিট করে।

২. Repository ইন্টারফেস

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
}

বর্ণনা:

  • JpaRepository ব্যবহার করে ডেটাবেজ অপারেশনগুলো সহজে পরিচালনা করা যায়।

৩. সার্ভিস ক্লাস

@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository employeeRepository;

    public void saveEmployee(Employee employee) {
        employeeRepository.save(employee);
    }

    public List<Employee> getAllEmployees() {
        return employeeRepository.findAll();
    }
}

৪. কন্ট্রোলার ক্লাস

@RestController
@RequestMapping("/employees")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @PostMapping("/fulltime")
    public void saveFullTimeEmployee(@RequestBody FullTimeEmployee employee) {
        employeeService.saveEmployee(employee);
    }

    @PostMapping("/parttime")
    public void savePartTimeEmployee(@RequestBody PartTimeEmployee employee) {
        employeeService.saveEmployee(employee);
    }

    @GetMapping
    public List<Employee> getAllEmployees() {
        return employeeService.getAllEmployees();
    }
}

Inheritance Mapping এর সুবিধা

  • জাভার অবজেক্ট-ওরিয়েন্টেড মডেলের সাথে ডেটাবেজ কাঠামোর সমন্বয়।
  • ডেটার পুনরাবৃত্তি হ্রাস।
  • ডেটাবেজ কোয়েরির সময় ফ্লেক্সিবিলিটি।

Inheritance Mapping সঠিকভাবে নির্বাচন এবং ব্যবহার করলে এটি ডেটাবেজ পারফরম্যান্স এবং রক্ষণাবেক্ষণে সহায়ক হয়।

Content added By

Single Table, Joined Table এবং Table Per Class Strategy

90
90

স্প্রিং ORM-এর মাধ্যমে Hibernate ব্যবহার করে ডেটাবেসে Inheritance Mapping করা যায়। Hibernate ইনহেরিটেন্সের জন্য তিনটি প্রধান স্ট্র্যাটেজি সরবরাহ করে:

  • Single Table Strategy
  • Joined Table Strategy
  • Table Per Class Strategy

প্রতিটি স্ট্র্যাটেজি একটি নির্দিষ্ট ডেটাবেস কাঠামোতে ডেটা সংরক্ষণের পদ্ধতি নির্দেশ করে।


Single Table Strategy

বৈশিষ্ট্য

  • পুরো ইনহেরিটেন্স হায়ারার্কি একটি মাত্র টেবিলে সংরক্ষণ করা হয়।
  • প্রতিটি সাবক্লাসের জন্য অতিরিক্ত কলাম যুক্ত হয়।
  • ডিসক্রিমিনেটর কলাম ব্যবহৃত হয় সাবক্লাসগুলো পার্থক্য করতে।

Entity ক্লাস উদাহরণ

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and Setters
}

@Entity
@DiscriminatorValue("FullTime")
public class FullTimeEmployee extends Employee {
    private double salary;

    // Getters and Setters
}

@Entity
@DiscriminatorValue("PartTime")
public class PartTimeEmployee extends Employee {
    private double hourlyRate;

    // Getters and Setters
}

SQL টেবিল

CREATE TABLE employee (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    salary DOUBLE,
    hourlyRate DOUBLE,
    type VARCHAR(255)
);

Joined Table Strategy

বৈশিষ্ট্য

  • প্রতিটি ক্লাসের জন্য পৃথক টেবিল তৈরি হয়।
  • প্যারেন্ট টেবিল এবং চাইল্ড টেবিলের মধ্যে JOIN সম্পর্ক থাকে।
  • ডেটা নরমালাইজড হয় এবং ডিস্ক স্পেস বাঁচে।

Entity ক্লাস উদাহরণ

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and Setters
}

@Entity
public class FullTimeEmployee extends Employee {
    private double salary;

    // Getters and Setters
}

@Entity
public class PartTimeEmployee extends Employee {
    private double hourlyRate;

    // Getters and Setters
}

SQL টেবিল

CREATE TABLE employee (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255)
);

CREATE TABLE full_time_employee (
    id BIGINT PRIMARY KEY,
    salary DOUBLE,
    FOREIGN KEY (id) REFERENCES employee(id)
);

CREATE TABLE part_time_employee (
    id BIGINT PRIMARY KEY,
    hourlyRate DOUBLE,
    FOREIGN KEY (id) REFERENCES employee(id)
);

Table Per Class Strategy

বৈশিষ্ট্য

  • প্রতিটি ক্লাসের জন্য একটি টেবিল তৈরি হয়।
  • প্যারেন্ট ক্লাসের ডেটা প্রতিটি চাইল্ড টেবিলে পুনরাবৃত্ত হয়।
  • InheritanceType.TABLE_PER_CLASS ব্যবহৃত হয়।

Entity ক্লাস উদাহরণ

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and Setters
}

@Entity
public class FullTimeEmployee extends Employee {
    private double salary;

    // Getters and Setters
}

@Entity
public class PartTimeEmployee extends Employee {
    private double hourlyRate;

    // Getters and Setters
}

SQL টেবিল

CREATE TABLE full_time_employee (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    salary DOUBLE
);

CREATE TABLE part_time_employee (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    hourlyRate DOUBLE
);

কোন স্ট্র্যাটেজি কখন ব্যবহার করবেন

স্ট্র্যাটেজিসুবিধাঅসুবিধাব্যবহারের ক্ষেত্র
Single Table Strategyদ্রুত পারফর্মেন্স, কম জটিলতাডিস্ক স্পেস অপচয়, অতিরিক্ত null ভ্যালুছোট ইনহেরিটেন্স হায়ারার্কি
Joined Table Strategyডেটা নরমালাইজড, ডিস্ক স্পেস সাশ্রয়ীJOIN অপারেশনের কারণে ধীরগতিরবড় ও জটিল ইনহেরিটেন্স কাঠামো
Table Per Class Strategyটেবিল গুলো একে অপরের সাথে স্বাধীনপ্যারেন্ট ডেটার পুনরাবৃত্তিবিশেষ ক্ষেত্রে যেখানে স্বাধীন টেবিল প্রয়োজন

সারাংশ

স্প্রিং ORM এবং Hibernate দিয়ে Inheritance Mapping করার জন্য তিনটি স্ট্র্যাটেজি রয়েছে: Single Table, Joined Table এবং Table Per Class। প্রতিটি স্ট্র্যাটেজি ডেটাবেস অপারেশনের নির্দিষ্ট প্রয়োজন অনুযায়ী ব্যবহার করা হয়। সঠিক স্ট্র্যাটেজি বাছাই করলে পারফর্মেন্স উন্নত হয় এবং ডেটাবেস ম্যানেজমেন্ট সহজ হয়।

Content added By

উদাহরণ সহ Inheritance Mapping

72
72

Inheritance Mapping হল Hibernate বা JPA-তে Entity ক্লাসের মধ্যে ইনহেরিটেন্স (Inheritance) সম্পর্ক পরিচালনা করার একটি পদ্ধতি। এটি ডাটাবেসে অবজেক্ট ওরিয়েন্টেড ইনহেরিটেন্স মডেল কিভাবে বাস্তবায়ন করা হবে তা সংজ্ঞায়িত করে। Hibernate বা JPA ইনহেরিটেন্স ব্যবহারের জন্য তিনটি প্রধান স্ট্র্যাটেজি প্রদান করে:

  1. Single Table (একক টেবিল)
  2. Table Per Class (প্রতিটি ক্লাসের জন্য আলাদা টেবিল)
  3. Joined Table (যোগ করা টেবিল)

নিচে প্রতিটি স্ট্র্যাটেজি উদাহরণসহ ব্যাখ্যা করা হলো।


১. Single Table স্ট্র্যাটেজি

Single Table স্ট্র্যাটেজি-তে সকল সাবক্লাসের ডেটা একটি মাত্র টেবিলে সংরক্ষিত হয়। এটি সর্বোচ্চ পারফরম্যান্স প্রদান করে কারণ কোয়্যারিতে একাধিক টেবিলের যোগ প্রয়োজন হয় না।

উদাহরণ:

Entity ক্লাস
import jakarta.persistence.*;

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public abstract class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and Setters
}

@Entity
@DiscriminatorValue("FullTime")
public class FullTimeEmployee extends Employee {
    private Double salary;

    // Getters and Setters
}

@Entity
@DiscriminatorValue("PartTime")
public class PartTimeEmployee extends Employee {
    private Double hourlyRate;

    // Getters and Setters
}
টেবিল গঠন

Hibernate employees নামে একটি টেবিল তৈরি করবে যেখানে type কলাম FullTime বা PartTime নির্দেশ করবে।


২. Table Per Class স্ট্র্যাটেজি

Table Per Class স্ট্র্যাটেজি-তে প্রতিটি ক্লাসের জন্য আলাদা টেবিল তৈরি হয়। এটি ব্যবহার করলে প্রতিটি টেবিল আলাদাভাবে প্রশ্ন করা সম্ভব, তবে কোয়্যারি করতে হলে যোগ প্রয়োজন হতে পারে।

উদাহরণ:

Entity ক্লাস
import jakarta.persistence.*;

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and Setters
}

@Entity
public class FullTimeEmployee extends Employee {
    private Double salary;

    // Getters and Setters
}

@Entity
public class PartTimeEmployee extends Employee {
    private Double hourlyRate;

    // Getters and Setters
}
টেবিল গঠন

Hibernate full_time_employee এবং part_time_employee নামে দুটি আলাদা টেবিল তৈরি করবে। প্রতিটি টেবিলে ইনহেরিট করা ফিল্ডগুলো সংরক্ষণ থাকবে।


৩. Joined Table স্ট্র্যাটেজি

Joined Table স্ট্র্যাটেজি-তে প্যারেন্ট ক্লাস এবং সাবক্লাসের জন্য আলাদা টেবিল তৈরি হয়। এটি ডাটার স্বাভাবিকীকরণ নিশ্চিত করে এবং মেমোরি ব্যবহার দক্ষ করে তোলে।

উদাহরণ:

Entity ক্লাস
import jakarta.persistence.*;

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and Setters
}

@Entity
public class FullTimeEmployee extends Employee {
    private Double salary;

    // Getters and Setters
}

@Entity
public class PartTimeEmployee extends Employee {
    private Double hourlyRate;

    // Getters and Setters
}
টেবিল গঠন

Hibernate নিম্নলিখিত টেবিল তৈরি করবে:

  1. employee টেবিল (শুধুমাত্র id এবং name ফিল্ড ধারণ করবে)।
  2. full_time_employee টেবিল (salary ধারণ করবে)।
  3. part_time_employee টেবিল (hourlyRate ধারণ করবে)।

Spring Configuration

Hibernate Configuration বা Spring Bean Configuration ব্যবহার করে SessionFactory তৈরি করতে হবে। উদাহরণ:

@Configuration
@EnableTransactionManagement
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/inheritance_demo");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan("com.example.model");
        return sessionFactory;
    }
}

CRUD অপারেশন বাস্তবায়ন

@Service
@Transactional
public class EmployeeService {
    @Autowired
    private SessionFactory sessionFactory;

    public void saveEmployee(Employee employee) {
        Session session = sessionFactory.getCurrentSession();
        session.save(employee);
    }

    public Employee getEmployeeById(Long id) {
        Session session = sessionFactory.getCurrentSession();
        return session.get(Employee.class, id);
    }
}

Main ক্লাস

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
                new AnnotationConfigApplicationContext(AppConfig.class);

        EmployeeService employeeService = context.getBean(EmployeeService.class);

        // Save FullTimeEmployee
        FullTimeEmployee fullTimeEmployee = new FullTimeEmployee();
        fullTimeEmployee.setName("John Doe");
        fullTimeEmployee.setSalary(80000.0);
        employeeService.saveEmployee(fullTimeEmployee);

        // Save PartTimeEmployee
        PartTimeEmployee partTimeEmployee = new PartTimeEmployee();
        partTimeEmployee.setName("Jane Doe");
        partTimeEmployee.setHourlyRate(40.0);
        employeeService.saveEmployee(partTimeEmployee);

        // Fetch Employee
        Employee employee = employeeService.getEmployeeById(fullTimeEmployee.getId());
        System.out.println("Fetched Employee: " + employee.getName());

        context.close();
    }
}

সারাংশ

Spring ORM-এর Inheritance Mapping বিভিন্ন স্ট্র্যাটেজি (Single Table, Table Per Class, এবং Joined Table) ব্যবহার করে Entity ইনহেরিটেন্স পরিচালনা করে। স্ট্র্যাটেজি নির্বাচন অ্যাপ্লিকেশনের পারফরম্যান্স এবং ডাটাবেস নকশার উপর নির্ভর করে। Inheritance Mapping ব্যবহার করে Object-Oriented মডেল এবং ডাটাবেসের মধ্যে সামঞ্জস্য বজায় রাখা সম্ভব।

Content added By
টপ রেটেড অ্যাপ

স্যাট অ্যাকাডেমী অ্যাপ

আমাদের অল-ইন-ওয়ান মোবাইল অ্যাপের মাধ্যমে সীমাহীন শেখার সুযোগ উপভোগ করুন।

ভিডিও
লাইভ ক্লাস
এক্সাম
ডাউনলোড করুন
Promotion