Java Persistence API (JPA) এবং Hibernate এর মাধ্যমে Spring ORM এ Inheritance Mapping ব্যবহার করে ডাটাবেসের টেবিলগুলোর মধ্যে Java ক্লাসগুলোর উত্তরাধিকার (Inheritance) সম্পর্ক প্রতিষ্ঠা করা যায়। এটি তখনই কার্যকর হয়, যখন বিভিন্ন ক্লাস একটি কমন বৈশিষ্ট্য (common property) শেয়ার করে।
Spring ORM এবং Hibernate এ Inheritance Mapping এর জন্য JPA এর কিছু অ্যানোটেশন ব্যবহার করা হয়। Hibernate তিন ধরনের Inheritance Strategy সমর্থন করে:
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>
@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
}
@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
}
@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
}
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();
}
}
Spring ORM এবং Hibernate এর মাধ্যমে Inheritance Mapping ডাটাবেসের সাথে Object-Oriented ডিজাইনের সম্পর্ক তৈরি করে ডেভেলপমেন্ট সহজ করে তোলে।
Inheritance Mapping হল Hibernate এবং Spring ORM এ ডেটাবেজ টেবিলের মধ্যে অবজেক্ট-ওরিয়েন্টেড ইনহেরিটেন্সের ধারণা বাস্তবায়নের একটি পদ্ধতি। জাভাতে যেভাবে ক্লাস ইনহেরিট করে সাবক্লাস তৈরি করা হয়, ঠিক সেভাবেই ডেটাবেজ টেবিলেও একই সম্পর্ক ম্যাপ করা যায়।
Hibernate বিভিন্ন কৌশল ব্যবহার করে Inheritance Mapping পরিচালনা করে, যা ডেটাবেজ ডিজাইন এবং পারফরম্যান্সের উপর নির্ভর করে।
Hibernate তিনটি প্রধান কৌশল সরবরাহ করে Inheritance Mapping এর জন্য:
সব ইনহেরিটেড ক্লাসের জন্য একটি মাত্র টেবিল তৈরি হয়। এটি খুবই সহজ এবং দ্রুত কার্যকর, কিন্তু বড় ডেটাবেজে অতিরিক্ত স্থান নষ্ট করতে পারে।
প্রত্যেক সাবক্লাসের জন্য আলাদা টেবিল তৈরি হয়। এটি স্পেস ব্যবহারে দক্ষ, তবে কোয়েরি জটিল হতে পারে।
প্রত্যেক ক্লাসের জন্য আলাদা টেবিল তৈরি হয় এবং তাদের মধ্যে সম্পর্ক বজায় রাখার জন্য জয়েন অপারেশন প্রয়োজন হয়। এটি খুবই নমনীয় কিন্তু ধীরগতির হতে পারে।
@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 কলাম নির্ধারণ করে যা সাবক্লাস চিহ্নিত করে।@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
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 সঠিকভাবে নির্বাচন এবং ব্যবহার করলে এটি ডেটাবেজ পারফরম্যান্স এবং রক্ষণাবেক্ষণে সহায়ক হয়।
স্প্রিং ORM-এর মাধ্যমে Hibernate ব্যবহার করে ডেটাবেসে Inheritance Mapping করা যায়। Hibernate ইনহেরিটেন্সের জন্য তিনটি প্রধান স্ট্র্যাটেজি সরবরাহ করে:
প্রতিটি স্ট্র্যাটেজি একটি নির্দিষ্ট ডেটাবেস কাঠামোতে ডেটা সংরক্ষণের পদ্ধতি নির্দেশ করে।
@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
}
CREATE TABLE employee (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255),
salary DOUBLE,
hourlyRate DOUBLE,
type VARCHAR(255)
);
JOIN
সম্পর্ক থাকে।@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
}
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)
);
@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
}
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। প্রতিটি স্ট্র্যাটেজি ডেটাবেস অপারেশনের নির্দিষ্ট প্রয়োজন অনুযায়ী ব্যবহার করা হয়। সঠিক স্ট্র্যাটেজি বাছাই করলে পারফর্মেন্স উন্নত হয় এবং ডেটাবেস ম্যানেজমেন্ট সহজ হয়।
Inheritance Mapping হল Hibernate বা JPA-তে Entity ক্লাসের মধ্যে ইনহেরিটেন্স (Inheritance) সম্পর্ক পরিচালনা করার একটি পদ্ধতি। এটি ডাটাবেসে অবজেক্ট ওরিয়েন্টেড ইনহেরিটেন্স মডেল কিভাবে বাস্তবায়ন করা হবে তা সংজ্ঞায়িত করে। Hibernate বা JPA ইনহেরিটেন্স ব্যবহারের জন্য তিনটি প্রধান স্ট্র্যাটেজি প্রদান করে:
নিচে প্রতিটি স্ট্র্যাটেজি উদাহরণসহ ব্যাখ্যা করা হলো।
Single Table স্ট্র্যাটেজি-তে সকল সাবক্লাসের ডেটা একটি মাত্র টেবিলে সংরক্ষিত হয়। এটি সর্বোচ্চ পারফরম্যান্স প্রদান করে কারণ কোয়্যারিতে একাধিক টেবিলের যোগ প্রয়োজন হয় না।
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 স্ট্র্যাটেজি-তে প্রতিটি ক্লাসের জন্য আলাদা টেবিল তৈরি হয়। এটি ব্যবহার করলে প্রতিটি টেবিল আলাদাভাবে প্রশ্ন করা সম্ভব, তবে কোয়্যারি করতে হলে যোগ প্রয়োজন হতে পারে।
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 স্ট্র্যাটেজি-তে প্যারেন্ট ক্লাস এবং সাবক্লাসের জন্য আলাদা টেবিল তৈরি হয়। এটি ডাটার স্বাভাবিকীকরণ নিশ্চিত করে এবং মেমোরি ব্যবহার দক্ষ করে তোলে।
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 নিম্নলিখিত টেবিল তৈরি করবে:
employee
টেবিল (শুধুমাত্র id
এবং name
ফিল্ড ধারণ করবে)।full_time_employee
টেবিল (salary
ধারণ করবে)।part_time_employee
টেবিল (hourlyRate
ধারণ করবে)।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;
}
}
@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);
}
}
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 মডেল এবং ডাটাবেসের মধ্যে সামঞ্জস্য বজায় রাখা সম্ভব।
Read more