TypeORM

TypeORM en NestJS - Explicación con Ejemplo

TypeORM es un ORM (Mapeo Objeto-Relacional) que se integra perfectamente con NestJS para manejar operaciones de base de datos de manera más intuitiva y productiva.

Configuración Básica

Primero, instala los paquetes necesarios:

bash
Copy
Download
npm install @nestjs/typeorm typeorm pg  # Para PostgreSQL

Ejemplo Completo

1. Definir una Entidad

Crea un archivo product.entity.ts:

typescript
Copy
Download
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity() // Decorador que marca la clase como entidad
export class Product {
  @PrimaryGeneratedColumn() // Columna primaria autoincremental
  id: number;

  @Column() // Columna normal
  name: string;

  @Column('decimal', { precision: 10, scale: 2 }) // Columna decimal
  price: number;

  @Column({ default: true }) // Columna con valor por defecto
  isAvailable: boolean;
}

2. Configurar TypeORM en el Módulo

En tu app.module.ts:

typescript
Copy
Download
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Product } from './product.entity';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'postgres', // Tipo de base de datos
      host: 'localhost',
      port: 5432,
      username: 'your_username',
      password: 'your_password',
      database: 'your_database',
      entities: [Product], // Lista de entidades
      synchronize: true, // ¡Solo para desarrollo! Sincroniza esquema automáticamente
    }),
    TypeOrmModule.forFeature([Product]), // Hace disponible el repositorio de Product
  ],
})
export class AppModule {}

3. Crear un Servicio con Operaciones CRUD

product.service.ts:

typescript
Copy
Download
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Product } from './product.entity';

@Injectable()
export class ProductService {
  constructor(
    @InjectRepository(Product) // Inyecta el repositorio de Product
    private productRepository: Repository<Product>,
  ) {}

  // Crear un nuevo producto
  async create(productData: Partial<Product>): Promise<Product> {
    const product = this.productRepository.create(productData);
    return await this.productRepository.save(product);
  }

  // Obtener todos los productos
  async findAll(): Promise<Product[]> {
    return await this.productRepository.find();
  }

  // Obtener un producto por ID
  async findOne(id: number): Promise<Product> {
    return await this.productRepository.findOne({ where: { id } });
  }

  // Actualizar un producto
  async update(id: number, updateData: Partial<Product>): Promise<Product> {
    await this.productRepository.update(id, updateData);
    return this.productRepository.findOne({ where: { id } });
  }

  // Eliminar un producto
  async remove(id: number): Promise<void> {
    await this.productRepository.delete(id);
  }
}

4. Crear un Controlador

product.controller.ts:

typescript
Copy
Download
import { Controller, Get, Post, Body, Param, Put, Delete } from '@nestjs/common';
import { ProductService } from './product.service';
import { Product } from './product.entity';

@Controller('products')
export class ProductController {
  constructor(private readonly productService: ProductService) {}

  @Post()
  async create(@Body() productData: Product): Promise<Product> {
    return this.productService.create(productData);
  }

  @Get()
  async findAll(): Promise<Product[]> {
    return this.productService.findAll();
  }

  @Get(':id')
  async findOne(@Param('id') id: number): Promise<Product> {
    return this.productService.findOne(id);
  }

  @Put(':id')
  async update(
    @Param('id') id: number,
    @Body() productData: Partial<Product>,
  ): Promise<Product> {
    return this.productService.update(id, productData);
  }

  @Delete(':id')
  async remove(@Param('id') id: number): Promise<void> {
    return this.productService.remove(id);
  }
}

¿Cómo Funciona?

  1. Entidades: Representan tablas en la base de datos. Los decoradores como @Column() definen las columnas.

  2. Repositorio: TypeORM crea automáticamente un repositorio para cada entidad, que proporciona métodos para operaciones CRUD.

  3. Inyección de Dependencias: NestJS inyecta automáticamente el repositorio en los servicios usando @InjectRepository().

  4. Operaciones: El repositorio proporciona métodos como find()save()update()delete(), etc.

Beneficios Clave:

  1. Código más limpio: No escribes SQL directamente.

  2. Independencia de la base de datos: Fácil cambiar entre PostgreSQL, MySQL, etc.

  3. Seguridad: Previene inyección SQL automáticamente.

  4. Relaciones: Maneja fácilmente relaciones entre tablas.

Este ejemplo muestra el flujo completo desde la entidad hasta el controlador, usando TypeORM para manejar todas las operaciones de base de datos de manera eficiente y segura.

Comentarios

Entradas más populares de este blog

48. ValidationPipe - Class Validator y Class Transformer

32-Modulos

49. Pipes Globales - A nivel de Aplicación