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 তে ডেটা তখনই লোড হয় যখন তা প্রয়োজন হয়। এই দুটি কৌশল ডেটা লোডিংকে আরও দক্ষ এবং কার্যকরী করে তোলে।
Read more