NestJS — Node.js للمؤسسات

تكامل TypeORM والكيانات

16 دقيقة الدرس 20 من 48

تكامل TypeORM والكيانات

تحتاج معظم التطبيقات الحقيقية إلى قاعدة بيانات. TypeORM أشهر ORM لـ NestJS — يُطابق أصناف TypeScript بجداول قاعدة البيانات، فتعمل بالكائنات بدل SQL الخام. يوفّر NestJS حزمة @nestjs/typeorm مخصّصة تدمجه بنظافة مع الوحدات وحقن التبعيات.

الاتصال بقاعدة البيانات

ثبّت الحزم واضبط الاتصال مرّة واحدة بـ TypeOrmModule.forRoot() في وحدة الجذر:

// npm install @nestjs/typeorm typeorm pg import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [ TypeOrmModule.forRoot({ type: 'postgres', host: 'localhost', port: 5432, username: 'app', password: 'secret', database: 'app', entities: [User], synchronize: true, // التطوير فقط — انظر التحذير أدناه }), ], }) export class AppModule {}
لا تستخدم synchronize: true في الإنتاج أبدًا. فهي تُعدّل مخطّطك تلقائيًا ليطابق الكيانات وقد تحذف أعمدة أو بيانات. في الإنتاج تستخدم الترحيلات (الدرس التالي) لتغييرات مخطّط مضبوطة وقابلة للمراجعة.

تعريف كيان

الكيان صنف مُزخرَف بـ @Entity()؛ وأعمدته خصائص مُزخرَفة بمُزخرِفات الأعمدة:

import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn } from 'typeorm'; @Entity('users') export class User { @PrimaryGeneratedColumn() id: number; @Column({ length: 120 }) name: string; @Column({ unique: true }) email: string; @Column({ default: true }) isActive: boolean; @CreateDateColumn() createdAt: Date; }

مُزخرِفات الأعمدة الشائعة

  • @PrimaryGeneratedColumn() — مفتاح أساسي متزايد تلقائيًا (أو 'uuid' لمعرّف UUID).
  • @Column() — عمود عادي، بخيارات كـ type وlength وnullable وunique وdefault.
  • @CreateDateColumn() / @UpdateDateColumn() — طوابع زمنية تلقائية.
  • @Index() — إضافة فهرس قاعدة بيانات لبحث أسرع.

تسجيل الكيان في وحدة ميزة

لاستخدام مستودع كيان داخل ميزة، سجّله بـ forFeature():

import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [TypeOrmModule.forFeature([User])], providers: [UsersService], }) export class UsersModule {}

هذا يجعل Repository<User> قابلًا للحقن في تلك الوحدة — وهو ما تستعلم وتحفظ به المستخدمين، في الدرس التالي.

forRoot مقابل forFeature: تضبط forRoot() اتصال قاعدة البيانات مرّة (وحدة الجذر)؛ وتُسجّل forFeature() مستودعات كيانات محدّدة للوحدات التي تحتاجها. ستتعرّف على نمط الوحدة الديناميكية هذا من قبل.

الإعداد غير المتزامن

في تطبيق حقيقي تأتي تفاصيل الاتصال من الإعداد لا من قيم مُرمَّزة. استخدم forRootAsync() لحقن ConfigService:

TypeOrmModule.forRootAsync({ inject: [ConfigService], useFactory: (config: ConfigService) => ({ type: 'postgres', url: config.get('DATABASE_URL'), autoLoadEntities: true, }), });

الخلاصة

يُطابق TypeORM الأصناف بالجداول. اضبط الاتصال بـ TypeOrmModule.forRoot() (أو forRootAsync() مع الإعداد)، وعرّف الكيانات بـ @Entity() ومُزخرِفات الأعمدة، وسجّلها لكل ميزة بـ forFeature(). أبقِ synchronize مُطفأة في الإنتاج. تاليًا نستخدم المستودع الذي يولّده هذا للقراءة والكتابة.