TypeORM এ Relationships কি?
TypeORM ডেটাবেস সম্পর্ক (Relationships) পরিচালনা করার জন্য একটি শক্তিশালী সিস্টেম সরবরাহ করে, যা ডেটাবেস টেবিলগুলির মধ্যে সম্পর্ক তৈরি এবং পরিচালনা করতে ব্যবহৃত হয়। ডেটাবেস সম্পর্কের তিনটি প্রধান ধরন রয়েছে:
- One-to-One Relationship: এক টেবিলের একটি রেকর্ড অন্য টেবিলের এক রেকর্ডের সাথে সম্পর্কিত থাকে।
- One-to-Many Relationship: এক টেবিলের একটি রেকর্ড অন্য টেবিলের অনেক রেকর্ডের সাথে সম্পর্কিত থাকে।
- Many-to-Many Relationship: এক টেবিলের একাধিক রেকর্ড অন্য টেবিলের একাধিক রেকর্ডের সাথে সম্পর্কিত থাকে।
TypeORM এই তিনটি সম্পর্কের ধরণকেই সহজে পরিচালনা করতে সাহায্য করে, যা ডেটাবেস মডেলিং এবং ডেটার সম্পর্কীয় কার্যাবলী সহজ করে তোলে।
TypeORM এর সম্পর্ক (Relationships) এর ধরন:
১. One-to-One Relationship
One-to-One Relationship তখন ব্যবহার করা হয় যখন একটি টেবিলের একটি রেকর্ড অন্য একটি টেবিলের এক রেকর্ডের সাথে সম্পর্কিত থাকে। সাধারণত, এক টেবিলের প্রাইমারি কির্ড একটি রেফারেন্স হিসেবে অন্য টেবিলের মধ্যে সংরক্ষিত থাকে।
উদাহরণ:
ধরা যাক, User এবং Profile টেবিলের মধ্যে একটি One-to-One সম্পর্ক রয়েছে। এক User এর একটি Profile থাকতে পারে এবং এক Profile এর একটি User থাকবে।
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from "typeorm";
import { Profile } from "./Profile";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToOne(() => Profile)
@JoinColumn()
profile: Profile;
}
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
bio: string;
}
এখানে, User ক্লাসে একটি One-to-One সম্পর্ক তৈরি করা হয়েছে যা Profile ক্লাসের সাথে যুক্ত। @JoinColumn() ব্যবহার করা হয়েছে Profile টেবিলের রেফারেন্স সংযুক্ত করতে।
২. One-to-Many Relationship
One-to-Many Relationship তখন ব্যবহৃত হয় যখন এক টেবিলের একটি রেকর্ড অনেক টেবিলের রেকর্ডের সাথে সম্পর্কিত থাকে। উদাহরণস্বরূপ, এক Author এর অনেক Books থাকতে পারে।
উদাহরণ:
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Book } from "./Book";
@Entity()
export class Author {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Book, book => book.author)
books: Book[];
}
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
import { Author } from "./Author";
@Entity()
export class Book {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(() => Author, author => author.books)
author: Author;
}
এখানে, Author এর একটি One-to-Many সম্পর্ক রয়েছে Book টেবিলের সাথে, যেখানে এক Author এর অনেক Book থাকতে পারে। ManyToOne ব্যবহার করা হয়েছে Book ক্লাসে।
৩. Many-to-Many Relationship
Many-to-Many Relationship তখন ব্যবহৃত হয় যখন এক টেবিলের একাধিক রেকর্ড অন্য টেবিলের একাধিক রেকর্ডের সাথে সম্পর্কিত থাকে। উদাহরণস্বরূপ, অনেক Student অনেক Course এ ভর্তি হতে পারে।
উদাহরণ:
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable } from "typeorm";
import { Course } from "./Course";
@Entity()
export class Student {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Course)
@JoinTable()
courses: Course[];
}
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity()
export class Course {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}
এখানে, Student এবং Course টেবিলের মধ্যে Many-to-Many সম্পর্ক তৈরি করা হয়েছে। @JoinTable() ব্যবহার করা হয়েছে সম্পর্কিত টেবিলের মধ্যে একটি মধ্যবর্তী টেবিল তৈরি করতে, যা এই সম্পর্কের সঠিক সংযোগ রাখতে সহায়তা করে।
TypeORM এ সম্পর্কের ব্যবহারের সুবিধা
- ডেটাবেস মডেলিংয়ের সহজতা: TypeORM এর সাহায্যে আপনি SQL ডেটাবেসের সম্পর্কগুলিকে সহজেই মডেল করতে পারেন। এই সম্পর্কগুলির মধ্যে প্রপার্টি বা সম্পর্কের সামঞ্জস্য রক্ষা করতে
@OneToMany(),@ManyToOne(),@OneToOne(), এবং@ManyToMany()ডেকোরেটর ব্যবহার করতে পারেন। - স্বয়ংক্রিয় মাইগ্রেশন: TypeORM সম্পর্কের মাধ্যমে আপনার ডেটাবেস মডেলগুলি স্বয়ংক্রিয়ভাবে সিঙ্ক্রোনাইজ করা যায়, যার ফলে সম্পর্কিত টেবিলগুলোর স্কিমা পরিবর্তন করার সময় আপনার কোডের সাথে সামঞ্জস্য বজায় রাখা সহজ হয়।
- কমপ্লেক্স ডেটা ম্যানিপুলেশন: TypeORM আপনাকে সম্পর্কের মাধ্যমে কমপ্লেক্স ডেটা ম্যানিপুলেশন সহজ করতে সহায়তা করে, যেমন একাধিক টেবিল থেকে ডেটা জোড়া (join) এবং সম্পর্কিত রেকর্ডের উপর বিভিন্ন অপারেশন করা।
- চেইনড কুয়েরি বিল্ডার: TypeORM কুয়েরি বিল্ডার সরবরাহ করে, যা ডেটাবেস সম্পর্কগুলির উপর আরও উন্নত কুয়েরি তৈরি করতে সাহায্য করে। এতে বিভিন্ন টেবিলের মধ্যে সম্পর্ক এবং তাদের উপর অপারেশন করা সহজ হয়।
- ভালো পারফরম্যান্স: TypeORM সম্পর্কগুলো অপটিমাইজ করে, যার ফলে ডেটাবেসের পারফরম্যান্সে কোন বাধা সৃষ্টি হয় না, বিশেষত বড় অ্যাপ্লিকেশন বা জটিল ডেটাবেসে কাজ করার সময়।
সারাংশ
TypeORM এর সাহায্যে One-to-One, One-to-Many, এবং Many-to-Many সম্পর্কগুলো সহজে তৈরি এবং পরিচালনা করা যায়। এটি ডেটাবেসের মডেলিং এবং সম্পর্কগুলির মাধ্যমে ডেটা ম্যানিপুলেশনকে সহজ করে তোলে, এবং তার সাথে Lazy Loading, Eager Loading, Query Builder ইত্যাদি ব্যবহার করে সম্পর্কিত ডেটা জোড়া এবং পরিচালনা করা সহজ হয়। TypeORM ডেভেলপারদের জন্য একটি শক্তিশালী টুল, যা ডেটাবেস সম্পর্কের সাথে কাজ করার সময় দ্রুত এবং কার্যকরী কোড তৈরি করতে সহায়তা করে।
TypeORM এ সম্পর্ক (Relationships)
TypeORM হল একটি Object-Relational Mapping (ORM) লাইব্রেরি যা জাভাস্ক্রিপ্ট বা টাইপস্ক্রিপ্টে ডেটাবেস পরিচালনা করতে ব্যবহৃত হয়। এটি ডেটাবেসের মধ্যে সম্পর্কগুলোকে Entity ক্লাসের মাধ্যমে মডেলিং করতে সাহায্য করে। TypeORM তে ডেটাবেসের বিভিন্ন সম্পর্ক (Relationship) তৈরি করা সম্ভব, যেমন One-to-One, One-to-Many, এবং Many-to-Many। এগুলো বিভিন্ন Entity ক্লাসের মধ্যে সম্পর্ক তৈরি করার জন্য ব্যবহৃত হয়, যাতে ডেটাবেসে সংশ্লিষ্ট টেবিলগুলোর মধ্যে উপযুক্ত সংযোগ তৈরি হয়।
এখানে আমরা One-to-One, One-to-Many, এবং Many-to-Many সম্পর্কের ধারণা এবং TypeORM তে এগুলি কীভাবে ইমপ্লিমেন্ট করা যায় তা দেখব।
১. One-to-One সম্পর্ক
One-to-One সম্পর্ক একটি সম্পর্ক যেখানে একটি রেকর্ড একটি রেকর্ডের সাথে সম্পর্কিত থাকে। অর্থাৎ, একটি টেবিলের একটি রেকর্ড অন্য টেবিলের শুধুমাত্র একটি রেকর্ডের সাথে সম্পর্কিত।
উদাহরণ:
ধরা যাক, আমাদের একটি User টেবিল এবং একটি Profile টেবিল রয়েছে। এখানে, একজন ইউজারের একটি প্রোফাইল থাকবে। এটি একটি One-to-One সম্পর্ক।
TypeORM কোড উদাহরণ:
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from "typeorm";
import { Profile } from "./Profile"; // Assuming Profile is another Entity
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToOne(() => Profile)
@JoinColumn() // This defines that the Profile is associated with the User entity
profile: Profile;
}
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
bio: string;
}
এখানে, User ক্লাসের profile প্রপার্টি @OneToOne() ডেকোরেটর দিয়ে Profile টেবিলের সাথে সম্পর্কিত করা হয়েছে এবং @JoinColumn() ডেকোরেটর দিয়ে এই সম্পর্কের জন্য কলাম সংজ্ঞায়িত করা হয়েছে।
২. One-to-Many সম্পর্ক
One-to-Many সম্পর্ক এমন একটি সম্পর্ক যেখানে একটি রেকর্ড অনেক রেকর্ডের সাথে সম্পর্কিত থাকে। সাধারণত, এটি যখন একটি রেকর্ড একাধিক সম্পর্কিত রেকর্ডের সাথে সংযুক্ত থাকে, তখন ব্যবহৃত হয়। উদাহরণস্বরূপ, একজন User একাধিক Post করতে পারে, এখানে One-to-Many সম্পর্ক রয়েছে।
TypeORM কোড উদাহরণ:
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Post } from "./Post"; // Assuming Post is another Entity
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Post, post => post.user) // One-to-many relation
posts: Post[];
}
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(() => User, user => user.posts) // Many-to-one relation (inverse side)
user: User;
}
এখানে, User Entity ক্লাসে @OneToMany() ডেকোরেটর ব্যবহার করে Post টেবিলের সাথে সম্পর্ক তৈরি করা হয়েছে। আবার Post Entity ক্লাসে @ManyToOne() ডেকোরেটর ব্যবহার করে সম্পর্কের বিপরীত দিক (inverse side) তৈরি করা হয়েছে। এর মাধ্যমে, একজন User একাধিক Post করতে পারে।
৩. Many-to-Many সম্পর্ক
Many-to-Many সম্পর্ক এমন একটি সম্পর্ক যেখানে একটি রেকর্ড একাধিক রেকর্ডের সাথে সম্পর্কিত হতে পারে এবং অন্য রেকর্ডও একইভাবে একাধিক রেকর্ডের সাথে সম্পর্কিত হতে পারে। উদাহরণস্বরূপ, একজন Student একাধিক Course এ অংশগ্রহণ করতে পারে এবং একটি Course একাধিক Student কে যুক্ত করতে পারে।
TypeORM কোড উদাহরণ:
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable } from "typeorm";
import { Course } from "./Course"; // Assuming Course is another Entity
@Entity()
export class Student {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Course)
@JoinTable() // This creates a join table for the many-to-many relationship
courses: Course[];
}
@Entity()
export class Course {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToMany(() => Student)
students: Student[];
}
এখানে, Student এবং Course Entity ক্লাসে @ManyToMany() ডেকোরেটর ব্যবহার করা হয়েছে। @JoinTable() ডেকোরেটরটি জোয়েন টেবিল তৈরি করতে ব্যবহৃত হয় যা এই সম্পর্কের জন্য মধ্যস্থতাকারী (intermediary) টেবিল হিসেবে কাজ করে।
সারাংশ
TypeORM এ One-to-One, One-to-Many, এবং Many-to-Many সম্পর্ক তৈরি করতে @OneToOne(), @OneToMany(), @ManyToOne(), এবং @ManyToMany() ডেকোরেটর ব্যবহার করা হয়। এই সম্পর্কগুলি Entity ক্লাসের মাধ্যমে ডেটাবেস টেবিলের মধ্যে সম্পর্ক তৈরি করতে সাহায্য করে। TypeORM এর মাধ্যমে ডেটাবেসের মধ্যে সম্পর্কিত টেবিলের কার্যকরী এবং দক্ষ ম্যানিপুলেশন সম্ভব, যা ডেভেলপারদের জন্য কোড লিখতে আরও সুবিধাজনক এবং সংহত হয়।
TypeORM এবং Relations ডেকোরেটর
TypeORM হল একটি Object-Relational Mapping (ORM) লাইব্রেরি যা TypeScript এবং JavaScript ডেভেলপমেন্টের জন্য ডিজাইন করা হয়েছে। TypeORM ডেটাবেসের সাথে যোগাযোগ সহজ করে তোলে এবং ডেটা মডেল এবং ডেটাবেস টেবিলের মধ্যে সম্পর্ক (Relations) নির্ধারণ করতে সাহায্য করে।
Relations ডেকোরেটর TypeORM-এ দুইটি বা তার অধিক টেবিলের মধ্যে সম্পর্ক তৈরি করতে ব্যবহৃত হয়। এই ডেকোরেটরগুলি ব্যবহার করে আপনি One-to-One, One-to-Many, Many-to-One, এবং Many-to-Many সম্পর্ক তৈরি করতে পারেন।
Relations ডেকোরেটর প্রকার
TypeORM-এ সাধারণত চার ধরনের সম্পর্ক তৈরি করা হয়:
- One-to-One Relation: এক টেবিলের একটি রেকর্ড অন্য টেবিলের একটিতে সম্পর্কিত।
- One-to-Many Relation: এক টেবিলের একটি রেকর্ড অন্য টেবিলের একাধিক রেকর্ডের সাথে সম্পর্কিত।
- Many-to-One Relation: একাধিক রেকর্ড এক টেবিলের একটি রেকর্ডের সাথে সম্পর্কিত।
- Many-to-Many Relation: একাধিক রেকর্ড একাধিক রেকর্ডের সাথে সম্পর্কিত।
এখানে প্রতিটি সম্পর্ক তৈরি করার জন্য @OneToOne, @OneToMany, @ManyToOne, এবং @ManyToMany ডেকোরেটর ব্যবহার করা হয়।
১. One-to-One Relation
একটি One-to-One সম্পর্ক তৈরি করতে @OneToOne ডেকোরেটর ব্যবহার করা হয়। এখানে, একটি রেকর্ড অন্য টেবিলের একটিতে সম্পর্কিত থাকবে।
উদাহরণ:
ধরা যাক, আপনি একটি User টেবিল এবং একটি Profile টেবিল তৈরি করছেন, যেখানে প্রতিটি User এর একটিই Profile রয়েছে।
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from "typeorm";
import { Profile } from "./Profile";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToOne(() => Profile)
@JoinColumn() // This will join the columns of the two tables
profile: Profile;
}
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
bio: string;
}
এখানে, User টেবিলের profile কলামটি Profile টেবিলের সাথে যুক্ত। @OneToOne ডেকোরেটরটি দুই টেবিলের মধ্যে সম্পর্ক তৈরি করছে এবং @JoinColumn ডেকোরেটরটি তাদের মধ্যে ফিজিক্যালি সম্পর্ক স্থাপন করে।
২. One-to-Many Relation
একটি One-to-Many সম্পর্ক তৈরি করতে @OneToMany এবং @ManyToOne ডেকোরেটর ব্যবহার করা হয়। এক টেবিলের একটি রেকর্ড অন্য টেবিলের একাধিক রেকর্ডের সাথে সম্পর্কিত।
উদাহরণ:
ধরা যাক, Category এবং Product টেবিলের মধ্যে One-to-Many সম্পর্ক তৈরি করতে চাই। এখানে, একটি Category এর একাধিক Product থাকবে।
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Product } from "./Product";
@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Product, product => product.category)
products: Product[];
}
@Entity()
export class Product {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToOne(() => Category, category => category.products)
category: Category;
}
এখানে, Category টেবিলের একটিতে একাধিক Product সম্পর্কিত থাকবে। @OneToMany ডেকোরেটরটি Category টেবিলের উপর ব্যবহার করা হয়েছে এবং @ManyToOne ডেকোরেটরটি Product টেবিলের উপর।
৩. Many-to-One Relation
একটি Many-to-One সম্পর্ক তৈরি করতে @ManyToOne এবং @OneToMany ডেকোরেটর ব্যবহার করা হয়। একাধিক রেকর্ড এক টেবিলের একটি রেকর্ডের সাথে সম্পর্কিত থাকে।
উদাহরণ:
এটি আগের উদাহরণের মতোই, তবে এখানেও Product টেবিলের মধ্যে Many-to-One সম্পর্ক এবং Category টেবিলের মধ্যে One-to-Many সম্পর্ক তৈরি করা হচ্ছে।
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
import { Category } from "./Category";
@Entity()
export class Product {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToOne(() => Category, category => category.products)
category: Category;
}
এখানে, Product টেবিলের category একাধিক রেকর্ডের মাধ্যমে Category টেবিলের একটি রেকর্ডের সাথে সম্পর্কিত।
৪. Many-to-Many Relation
একটি Many-to-Many সম্পর্ক তৈরি করতে @ManyToMany এবং @JoinTable ডেকোরেটর ব্যবহার করা হয়। একাধিক রেকর্ড একাধিক রেকর্ডের সাথে সম্পর্কিত থাকে।
উদাহরণ:
ধরা যাক, একটি Student টেবিল এবং একটি Course টেবিল আছে, যেখানে একটি Student একাধিক Course নিবন্ধন করতে পারে এবং একটি Course এ একাধিক Student থাকতে পারে।
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable } from "typeorm";
import { Course } from "./Course";
@Entity()
export class Student {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Course)
@JoinTable()
courses: Course[];
}
@Entity()
export class Course {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Student)
students: Student[];
}
এখানে, Student এবং Course এর মধ্যে Many-to-Many সম্পর্ক তৈরি করা হয়েছে। @JoinTable ডেকোরেটরটি সম্পর্কের মধ্যবর্তী টেবিল তৈরির জন্য ব্যবহৃত হয়, যা দুইটি টেবিলের সম্পর্ক নির্দেশ করে।
সারাংশ
TypeORM-এ Relations ডেকোরেটর ব্যবহারের মাধ্যমে আপনি একাধিক টেবিলের মধ্যে সম্পর্ক তৈরি করতে পারেন। এটি One-to-One, One-to-Many, Many-to-One, এবং Many-to-Many সম্পর্ক তৈরি করতে সহায়ক। TypeORM এর মাধ্যমে এই সম্পর্কগুলির মধ্যে ডেটা খুব সহজে ম্যাপ এবং পরিচালনা করা যায়, যা ডেটাবেস ডিজাইন এবং কোডিং প্রক্রিয়াকে আরো কার্যকরী করে তোলে।
Cascade Operations
Cascade Operations হল একটি ডেটাবেস সম্পর্কিত ধারণা, যেখানে একটি এন্টিটি (entity) এর পরিবর্তনের সাথে সম্পর্কিত অন্যান্য এন্টিটি গুলোর ওপর স্বয়ংক্রিয়ভাবে কিছু অপারেশন (যেমন INSERT, UPDATE, DELETE) প্রয়োগ করা হয়। TypeORM এ, আপনি Cascade Operations ব্যবহার করে নির্দিষ্ট সম্পর্কিত এন্টিটিগুলোর উপর একাধিক অপারেশন চালাতে পারেন।
TypeORM এ Cascade Operations সাধারণত Relations ডেকোরেটরের মাধ্যমে কনফিগার করা হয়। এটি মূলত OneToMany, ManyToOne, OneToOne ইত্যাদি সম্পর্কের ক্ষেত্রে ব্যবহার করা হয়, যেখানে সম্পর্কিত এন্টিটি গুলোর উপর ক্যাসকেড অপারেশন প্রযোজ্য হয়।
Cascade Operations ব্যবহার করার উদাহরণ:
ধরা যাক, আমাদের দুটি এন্টিটি রয়েছে: User এবং Post। এখানে একজন User এর অনেকগুলো Post থাকতে পারে (One-to-Many সম্পর্ক) এবং আমরা চাই যখন User কে ডিলিট করা হবে, তখন তার সম্পর্কিত Post গুলোও ডিলিট হয়ে যাবে।
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Post } from "./Post";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(type => Post, post => post.user, { cascade: true })
posts: Post[];
}
এখানে, cascade: true ব্যবহার করে আমরা জানাচ্ছি যে, User ডিলিট হলে তার সম্পর্কিত Post গুলোও ডিলিট হবে।
Post Entity:
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
import { User } from "./User";
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(type => User, user => user.posts)
user: User;
}
এখন, যদি আমরা User কে ডিলিট করি, TypeORM স্বয়ংক্রিয়ভাবে সেই ইউজারের সমস্ত Post ডিলিট করবে।
import { createConnection } from "typeorm";
import { User } from "./entity/User";
import { Post } from "./entity/Post";
createConnection().then(async connection => {
const userRepository = connection.getRepository(User);
const postRepository = connection.getRepository(Post);
// User create
const user = new User();
user.name = "John";
const post1 = new Post();
post1.title = "Post 1";
post1.user = user;
const post2 = new Post();
post2.title = "Post 2";
post2.user = user;
await userRepository.save(user);
await postRepository.save([post1, post2]);
console.log("User and Posts saved");
// Delete user and cascade delete posts
await userRepository.remove(user);
console.log("User and Posts deleted");
}).catch(error => console.log(error));
এখানে, cascade: true এর মাধ্যমে User ডিলিট করার সাথে সাথে তার সম্পর্কিত Post গুলোও ডিলিট হয়ে যাবে।
Eager vs Lazy Loading
Eager Loading এবং Lazy Loading হল ডেটাবেস সম্পর্কিত দুটি পদ্ধতি যার মাধ্যমে আপনি সম্পর্কিত এন্টিটি গুলোর ডেটা লোড করার কৌশল নির্ধারণ করতে পারেন। TypeORM এ এই দুটি পদ্ধতি ব্যবহৃত হয় যখন এক এন্টিটির সাথে সম্পর্কিত অন্য এন্টিটি গুলোর ডেটা লোড করতে হয়।
১. Eager Loading
Eager Loading হল এমন একটি কৌশল যেখানে সম্পর্কিত ডেটা স্বয়ংক্রিয়ভাবে লোড করা হয়। অর্থাৎ, যখন আপনি একটি এন্টিটি লোড করেন, তখন তার সম্পর্কিত এন্টিটি গুলোকেও একই সাথে লোড করা হয়।
TypeORM এ Eager Loading এর জন্য @JoinColumn বা @ManyToOne এর মতো সম্পর্ক ডেকোরেটর ব্যবহার করা হয়। Eager Loading ডেটা লোড করার সময় সম্পর্কিত সমস্ত এন্টিটির ডেটা একটি রিকোয়েস্টেই লোড হয়।
উদাহরণ: Eager Loading
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Post } from "./Post";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(type => Post, post => post.user, { eager: true })
posts: Post[];
}
এখানে, { eager: true } ব্যবহার করে আমরা জানাচ্ছি যে, যখন User লোড হবে, তখন তার সাথে সম্পর্কিত Post গুলোও স্বয়ংক্রিয়ভাবে লোড হবে।
Post Entity:
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
import { User } from "./User";
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(type => User, user => user.posts)
user: User;
}
এখন, আপনি User ইনস্ট্যান্স লোড করলে, তার সম্পর্কিত Post গুলিও একসাথে লোড হবে:
createConnection().then(async connection => {
const userRepository = connection.getRepository(User);
// Find a user and its posts using eager loading
const user = await userRepository.findOne({ where: { id: 1 } });
console.log(user);
console.log(user.posts); // Posts will be loaded eagerly
}).catch(error => console.log(error));
২. Lazy Loading
Lazy Loading হল এমন একটি কৌশল যেখানে সম্পর্কিত ডেটা শুধুমাত্র তখনই লোড হয় যখন তা প্রয়োজন হয়। অর্থাৎ, সম্পর্কিত এন্টিটির ডেটা তখনই লোড হবে যখন আপনি সেই সম্পর্কিত ডেটা অ্যাক্সেস করবেন।
TypeORM এ Lazy Loading ব্যবহার করতে হলে আপনাকে Promise রিটার্ন করতে হবে। এই জন্য lazy: true প্যারামিটার ব্যবহার করতে হয়।
উদাহরণ: Lazy Loading
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";
import { Post } from "./Post";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(type => Post, post => post.user, { lazy: true })
posts: Promise<Post[]>;
}
এখানে, { lazy: true } ব্যবহার করা হয়েছে, যার ফলে posts এর ডেটা তখনই লোড হবে যখন আপনি সেটি অ্যাক্সেস করবেন।
Post Entity:
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";
import { User } from "./User";
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(type => User, user => user.posts)
user: User;
}
এখন, আপনি User এর posts অ্যাক্সেস করবেন তখনই সেই Post গুলি লোড হবে:
createConnection().then(async connection => {
const userRepository = connection.getRepository(User);
// Find user with lazy-loaded posts
const user = await userRepository.findOne({ where: { id: 1 } });
// Lazy loading posts
const posts = await user.posts;
console.log(posts); // Posts will be loaded lazily
}).catch(error => console.log(error));
এখানে, posts শুধুমাত্র তখনই লোড হবে যখন আপনি সেটি অ্যাক্সেস করবেন।
সারাংশ
Cascade Operations TypeORM-এ ডেটাবেস সম্পর্কিত কাজগুলোকে সহজ করে তোলে, যেমন যখন একটি এন্টিটি ডিলিট হয় তখন তার সম্পর্কিত এন্টিটি গুলোর উপর স্বয়ংক্রিয়ভাবে অপারেশন প্রয়োগ করা। Eager Loading এবং Lazy Loading হল ডেটা লোডিং কৌশল যা TypeORM এ ব্যবহার করা যায়। Eager Loading তে সম্পর্কিত সমস্ত ডেটা একত্রে লোড হয়, যখন Lazy Loading তে ডেটা তখনই লোড হয় যখন তা প্রয়োজন হয়। এই দুটি কৌশল ডেটা লোডিংকে আরও দক্ষ এবং কার্যকরী করে তোলে।
TypeORM-এ Relation এবং Join Tables
TypeORM একটি শক্তিশালী ORM (Object-Relational Mapping) টুল, যা JavaScript বা TypeScript দিয়ে ডেটাবেস ম্যানিপুলেশন সহজ করে তোলে। TypeORM সম্পর্কিত টেবিলগুলির মধ্যে join অপারেশন এবং relation ব্যবস্থাপনা করার জন্য অত্যন্ত কার্যকরী ফিচার সরবরাহ করে। এর মাধ্যমে আপনি One-to-One, One-to-Many, এবং Many-to-Many সম্পর্ক তৈরি করতে পারেন।
এখানে, আমরা Join Tables এবং Relation Options এর মাধ্যমে টেবিল সম্পর্কিত বিভিন্ন ডেটাবেস অপারেশন করার পদ্ধতি দেখবো।
১. TypeORM Relations কি?
TypeORM-এ, relations হল দুটি বা ততোধিক টেবিলের মধ্যে সম্পর্ক প্রতিষ্ঠা করার পদ্ধতি। এটি একটি ক্লাসের (Entity) মধ্যে অন্য ক্লাসের রেফারেন্স অন্তর্ভুক্ত করতে সাহায্য করে, যা ডেটাবেস টেবিলের মধ্যে সম্পর্ক তৈরি করে।
TypeORM-এ সম্পর্ক তৈরি করতে, আপনি @ManyToOne, @OneToMany, @ManyToMany, এবং @OneToOne ডেকোরেটর ব্যবহার করেন।
২. Relation Types
TypeORM-এ সম্পর্ক তিনটি মূল ধরনের হতে পারে:
- One-to-One (এক-এ-এক সম্পর্ক): এটি এমন একটি সম্পর্ক যেখানে একটি রেকর্ড একটি নির্দিষ্ট রেকর্ডের সাথে সম্পর্কিত থাকে। উদাহরণস্বরূপ, একজন ব্যবহারকারীর একটি প্রোফাইল।
- One-to-Many (এক-এ-অনেক সম্পর্ক): এখানে একটি রেকর্ড অনেক রেকর্ডের সাথে সম্পর্কিত থাকে। যেমন, একটি ব্লগ পোস্টের অনেক মন্তব্য।
- Many-to-Many (অনেক-এ-অনেক সম্পর্ক): এখানে অনেক রেকর্ড অনেক রেকর্ডের সাথে সম্পর্কিত থাকে। যেমন, একটি শিক্ষার্থী একাধিক কোর্সে ভর্তির মধ্যে যুক্ত থাকতে পারে।
৩. One-to-One Relation
একটি One-to-One সম্পর্ক তৈরি করতে @OneToOne এবং @JoinColumn ডেকোরেটর ব্যবহার করা হয়।
উদাহরণ: One-to-One Relation
ধরা যাক, আমরা একটি User এবং একটি Profile ক্লাস তৈরি করছি যেখানে প্রতিটি ইউজারের একটি প্রোফাইল থাকবে।
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from 'typeorm';
import { Profile } from './Profile';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToOne(() => Profile)
@JoinColumn() // এই লাইনটি প্রোফাইলের সাথে যুক্ত টেবিলটি নির্দিষ্ট করে
profile: Profile;
}
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number;
@Column()
bio: string;
}
এখানে, User এবং Profile ক্লাসের মধ্যে এক-এ-এক সম্পর্ক স্থাপন করা হয়েছে, যেখানে User এর একটি প্রোফাইল থাকবে।
৪. One-to-Many এবং Many-to-One Relations
এখানে, একটি One-to-Many সম্পর্কের মধ্যে একটি User অনেক Post এর সাথে সম্পর্কিত হতে পারে। TypeORM-এ এই সম্পর্কটি তৈরি করতে @OneToMany এবং @ManyToOne ডেকোরেটর ব্যবহার করা হয়।
উদাহরণ: One-to-Many Relation
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
import { Post } from './Post';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Post, post => post.user) // One User can have many Posts
posts: Post[];
}
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@ManyToOne(() => User, user => user.posts) // Many Posts can belong to one User
user: User;
}
এখানে, User ক্লাসে OneToMany ডেকোরেটর ব্যবহার করা হয়েছে যা এক ব্যবহারকারীর অনেক পোস্ট থাকতে পারে, এবং Post ক্লাসে ManyToOne ডেকোরেটর ব্যবহার করা হয়েছে যাতে প্রতিটি পোস্ট একটি নির্দিষ্ট ইউজারের সাথে সম্পর্কিত থাকে।
৫. Many-to-Many Relation
Many-to-Many সম্পর্কের মধ্যে দুইটি টেবিলের মধ্যে অনেক রেকর্ড একে অপরের সাথে সম্পর্কিত থাকে। উদাহরণস্বরূপ, একটি শিক্ষার্থী অনেক কোর্সে ভর্তি হতে পারে এবং একটি কোর্সে অনেক শিক্ষার্থী থাকতে পারে।
উদাহরণ: Many-to-Many Relation
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable } from 'typeorm';
import { Student } from './Student';
@Entity()
export class Course {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Student)
@JoinTable() // Many-to-many সম্পর্কের জন্য JoinTable ব্যবহৃত হয়
students: Student[];
}
@Entity()
export class Student {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@ManyToMany(() => Course)
students: Course[];
}
এখানে, Course এবং Student ক্লাসের মধ্যে একটি Many-to-Many সম্পর্ক স্থাপন করা হয়েছে। @JoinTable() ডেকোরেটর ব্যবহার করা হয়েছে টেবিলের মধ্যে সম্পর্কের জন্য একটি Join Table তৈরি করতে।
৬. Join Tables in TypeORM
Many-to-Many সম্পর্কের ক্ষেত্রে, TypeORM একটি Join Table তৈরি করে যা উভয় টেবিলের মধ্যে সম্পর্ক বজায় রাখে। @JoinTable() ডেকোরেটর ব্যবহার করলে TypeORM নিজে থেকেই একটি টেবিল তৈরি করবে যেখানে উভয় টেবিলের প্রাইমারি কী থাকবে।
উদাহরণস্বরূপ, শিক্ষার্থী এবং কোর্সের মধ্যে সম্পর্কের জন্য, TypeORM একটি student_courses নামে টেবিল তৈরি করবে যা student_id এবং course_id ফিল্ড থাকবে।
৭. Relation Options
TypeORM সম্পর্কিত বিভিন্ন options সরবরাহ করে যা সম্পর্কের আচরণ কাস্টমাইজ করতে সাহায্য করে:
- cascade: ডেটাবেস অপারেশনগুলির জন্য একাধিক অটোমেটিক অপশন যেমন
insert,update,remove। - eager:
eagerঅপশন ব্যবহার করে সম্পর্কিত টেবিলগুলির ডেটা সরাসরি লোড করা যায়। - lazy:
lazyঅপশন ব্যবহার করে সম্পর্কিত ডেটা লোড করা বিলম্বিত করা যায়।
Cascade উদাহরণ:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Post, post => post.user, { cascade: true }) // Cascade insert/update/remove
posts: Post[];
}
Eager Loading উদাহরণ:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Post, post => post.user, { eager: true }) // Automatically load related posts
posts: Post[];
}
সারাংশ
TypeORM ডেটাবেস সম্পর্ক তৈরি এবং ম্যানেজ করার জন্য একটি শক্তিশালী ORM লাইব্রেরি। TypeORM ব্যবহার করে One-to-One, One-to-Many, এবং Many-to-Many সম্পর্ক খুব সহজে তৈরি করা যায় এবং @JoinTable() সহ বিভিন্ন relation options ব্যবহার করে সম্পর্কগুলির আচরণ কাস্টমাইজ করা যায়।
TypeORM-এর ডেকোরেটরগুলো (@ManyToOne, @OneToMany, @ManyToMany, @JoinColumn, ইত্যাদি) ডেটাবেস টেবিলগুলির মধ্যে সম্পর্ক সঠিকভাবে তৈরি এবং ম্যানেজ করতে সহায়তা করে, যার ফলে ডেটাবেস অপারেশনগুলির জটিলতা কমে যায়।
Read more