← Назад к вопросам

Какую ORM используешь в NestJS?

1.0 Junior🔥 201 комментариев
#Базы данных и SQL#Фреймворки и библиотеки

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

ORM в NestJS проектах

Я предпочитаю работать с TypeORM как основной ORM для NestJS приложений, но выбор инструмента зависит от требований проекта и командного опыта.

TypeORM — классический выбор

Почему TypeORM популярна в NestJS:

  • Native интеграция с NestJS (есть официальный @nestjs/typeorm модуль)
  • Отличная типизация благодаря TypeScript
  • Поддержка множества БД (PostgreSQL, MySQL, SQLite, Oracle и др.)
  • Богатый функционал: relations, migrations, query builder
// Пример использования TypeORM в NestJS
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
import { Post } from './post.entity';

@Entity('users')
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ type: 'varchar', length: 100 })
  email: string;

  @Column({ type: 'varchar', length: 100 })
  name: string;

  @OneToMany(() => Post, post => post.author, { cascade: true })
  posts: Post[];
}
// Сервис с TypeORM
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  async findById(id: string): Promise<User> {
    return this.usersRepository.findOne({
      where: { id },
      relations: ['posts'],
    });
  }

  async create(userData: CreateUserDto): Promise<User> {
    const user = this.usersRepository.create(userData);
    return this.usersRepository.save(user);
  }
}

Миграции в TypeORM

Одна из сильных сторон TypeORM — встроенная система миграций:

// Генерирование миграции
npm run typeorm migration:generate src/migrations/InitialSchema

// Запуск миграций
npm run typeorm migration:run

// Откат миграции
npm run typeorm migration:revert

Альтернативы и их особенности

Prisma — современный ORM:

// Prisma выглядит более лаконично
const user = await prisma.user.findUnique({
  where: { id: userId },
  include: { posts: true },
});
  • Преимущества: автогенерация типов, интуитивный API, отличная документация
  • Недостатки: меньше контроля над SQL, миграции могут быть медленнее

MikroORM:

@Entity()
export class User {
  @PrimaryKey()
  id: number;

  @Property()
  email: string;

  @OneToMany(() => Post, post => post.author)
  posts = new Collection<Post>(this);
}
  • Преимущества: конкурент TypeORM с лучшей производительностью в некоторых сценариях
  • Недостатки: меньший экосистем, сложнее найти примеры

Raw SQL/QueryBuilder:

// Иногда лучше писать SQL напрямую
const users = await this.usersRepository
  .createQueryBuilder('user')
  .leftJoinAndSelect('user.posts', 'posts')
  .where('posts.createdAt > :date', { date: new Date('2024-01-01') })
  .orderBy('user.name', 'ASC')
  .getMany();

Лучшие практики при работе с ORM

1. Используй QueryBuilder для сложных запросов

// Вместо загрузки всех данных и фильтрации в коде
const activePosts = await this.postsRepository
  .createQueryBuilder('post')
  .where('post.published = :published', { published: true })
  .andWhere('post.viewCount > :views', { views: 1000 })
  .orderBy('post.createdAt', 'DESC')
  .limit(10)
  .getMany();

2. Ленивая загрузка данных (Lazy Relations)

// Грузи только необходимые данные
const user = await this.usersRepository.findOne({
  where: { id },
  relations: ['profile', 'settings'], // only needed
});

3. Избегай N+1 проблемы

// ❌ Плохо — N+1 запросы
const users = await this.usersRepository.find();
for (const user of users) {
  user.posts = await this.postsRepository.find({
    where: { authorId: user.id }
  });
}

// ✅ Хорошо — один запрос
const users = await this.usersRepository.find({
  relations: ['posts'],
});

4. Используй индексы для частых поисков

@Entity('users')
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ type: 'varchar', length: 100 })
  @Index('idx_email') // Индекс для быстрого поиска по email
  email: string;
}

Мой подход в production проектах

  1. TypeORM как базовый ORM — он отлично работает с NestJS
  2. QueryBuilder для сложных запросов — более эффективно, чем ORM методы
  3. Raw SQL для критичных по производительности операций
  4. Миграции как source of truth для схемы БД
  5. Тесты с тестовой БД и откатом миграций

Итоги

Выбор ORM зависит от: ✓ Масштаба проекта (микросервис vs монолит) ✓ Команды (опыт с инструментом) ✓ Требований (производительность, гибкость, скорость разработки) ✓ БД (PostgreSQL, MySQL, прочие)

Я предпочитаю TypeORM в NestJS за его надежность, типизацию и экосистему.