Время чтения: 4 мин.
TypeORM — один из самых популярных ORM (Object-Relational Mapping) для TypeScript и Node.js. В сочетании с NestJS он позволяет удобно работать с базами данных, используя декларативный подход на основе сущностей (Entities) и репозиториев (Repositories).
В этом руководстве мы разберём:
- Настройку TypeORM в NestJS.
- Создание сущностей (Entities) и репозиториев (Repositories).
- CRUD-операции (Create, Read, Update, Delete).
- Связи между таблицами (One-to-One, Many-to-One, Many-to-Many).
- Миграции базы данных.
1. Установка и настройка TypeORM
Установка необходимых пакетов
npm install @nestjs/typeorm typeorm pg # PostgreSQL (или mysql2, sqlite3 и т. д.)
Подключение к базе данных
Добавим конфигурацию в app.module.ts
:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres', // Тип БД (mysql, sqlite, mssql и др.)
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'password',
database: 'nestjs_db',
entities: [__dirname + '/**/*.entity{.ts,.js}'], // Где искать сущности
synchronize: true, // Автоматическое обновление схемы (только для разработки!)
}),
],
})
export class AppModule {}
⚠️ Важно!
synchronize: true
автоматически обновляет схему БД, но не подходит для продакшена (используйте миграции).- Для разных СУБД (
postgres
,mysql
,sqlite
) настройки могут отличаться.
2. Создание сущности (Entity)
Сущность (Entity) — это класс, который описывает структуру таблицы в БД.
Пример: Сущность User
Создадим user.entity.ts
:
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity() // Декоратор указывает, что это сущность БД
export class User {
@PrimaryGeneratedColumn() // Автоинкрементный ID
id: number;
@Column() // Поле таблицы
name: string;
@Column({ unique: true }) // Уникальное поле
email: string;
@Column({ nullable: true }) // Необязательное поле
age?: number;
}
Регистрация сущности в модуле
Добавим TypeOrmModule.forFeature([User])
в users.module.ts
:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
@Module({
imports: [TypeOrmModule.forFeature([User])], // Регистрация репозитория
providers: [UsersService],
controllers: [UsersController],
})
export class UsersModule {}
Теперь UsersService
может внедрить Repository<User>
:
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 findAll(): Promise<User[]> {
return this.usersRepository.find();
}
async create(user: Partial<User>): Promise<User> {
return this.usersRepository.save(user);
}
}
3. CRUD-операции
Добавление методов в UsersController
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './user.entity';
@Controller('users')
export class UsersController {
constructor(private usersService: UsersService) {}
@Get()
async findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Post()
async create(@Body() user: User): Promise<User> {
return this.usersService.create(user);
}
@Get(':id')
async findOne(@Param('id') id: number): Promise<User> {
return this.usersService.findOne(id);
}
}
Основные методы TypeORM
Метод | Описание | Пример SQL |
---|---|---|
repository.find() | Получить все записи | SELECT * FROM users |
repository.findOne(id) | Найти по ID | SELECT * FROM users WHERE id = ? |
repository.save(entity) | Сохранить или обновить запись | INSERT INTO users ... |
repository.delete(id) | Удалить запись | DELETE FROM users WHERE id = ? |
repository.update(id, data) | Обновить запись | UPDATE users SET ... WHERE id = ? |
4. Связи между таблицами
One-to-Many (Пользователь → Посты)
// user.entity.ts
import { Entity, OneToMany } from 'typeorm';
import { Post } from './post.entity';
@Entity()
export class User {
@OneToMany(() => Post, (post) => post.author) // 1 пользователь → N постов
posts: Post[];
}
// post.entity.ts
import { Entity, ManyToOne } from 'typeorm';
import { User } from './user.entity';
@Entity()
export class Post {
@ManyToOne(() => User, (user) => user.posts) // N постов → 1 пользователь
author: User;
}
Many-to-Many (Посты ↔ Теги)
// post.entity.ts
import { Entity, ManyToMany, JoinTable } from 'typeorm';
import { Tag } from './tag.entity';
@Entity()
export class Post {
@ManyToMany(() => Tag)
@JoinTable() // Создаёт промежуточную таблицу
tags: Tag[];
}
// tag.entity.ts
import { Entity } from 'typeorm';
@Entity()
export class Tag {
name: string;
}
5. Миграции (Migrations)
Миграции помогают безопасно изменять схему БД.
Настройка TypeORM CLI
Создайте ormconfig.json
:
{
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "postgres",
"password": "password",
"database": "nestjs_db",
"entities": ["src/**/*.entity{.ts,.js}"],
"migrations": ["migrations/*{.ts,.js}"],
"cli": { "migrationsDir": "migrations" }
}
Создание и применение миграции
npx typeorm migration:create -n CreateUserTable # Создаёт файл миграции
npx typeorm migration:run # Применяет миграции
npx typeorm migration:revert # Откатывает последнюю миграцию
Заключение
- TypeORM + NestJS = мощный инструмент для работы с БД.
- Сущности (Entities) описывают структуру таблиц.
- Репозитории (Repositories) дают удобные методы для CRUD.
- Связи (
@OneToMany
,@ManyToMany
) упрощают работу с данными. - Миграции помогают безопасно обновлять схему БД.
Что дальше?
- Добавить валидацию данных (class-validator).
- Оптимизировать запросы с ленивой загрузкой (
{ lazy: true }
). - Использовать Docker для развёртывания PostgreSQL.
Документация:
Попробуйте создать своё приложение с этими инструментами! 🚀
Добавить комментарий