3. Backend/NestJS / / 2024. 3. 14. 19:22

[코드팩토리 NestJS 강의] Typeorm 사용해보기

728x90

 

NestJS에 Typeorm 설정하기

yarn add @nestjs/typeorm typeorm 설치하기

// app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PostsModule } from './posts/posts.module';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    PostsModule,
    TypeOrmModule.forRoot({
      // 데이터베이스 타입
      // VS코드에서 postgres와 연동할때 작성할때 작성했던 정보들을 입력
      type: 'postgres',
      host: '127.0.0.1',
      port: 5432,
      username: 'postgres',
      password: 'postgres',
      database: 'postgres',
      // 데이터베이스와 생성/연동될 모델들을 하나씩 넣을 예정
      entities: [],
      // NestJS에서 작성하는 타입ORM코드와 데이터베이스의 싱크를 자동으로 맞출것인지에 대한 유무
      // 개발환경에서는 true로 해놔야지 편함,
      // Production환경에서는 마음대로 데이터베이스의 구조가 바뀔 수 있기 때문에 false로 하여 자동연동을 막아야함
      synchronize: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

TypeOrmModule.forRoot() : TypeOrm과 NestJS를 연결할 수 있는 연결고리를 만들 수 있음. 그 안에 object를 넣어줘야하는데, 기본적으로 넣어야하는 몇가지 옵션이 존재한다.

옵션에 민감한 정보들도 입력을 해놓음 → 이부분들은 나중에 환경변수를 사용하기 시작하면서 조금씩 바꿔나갈 예정

(*아직은 할줄 모르니까 string값으로 넣어서 연동하기)

Entity로 테이블 생성하기

// posts > entities > posts.entity.ts

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class PostsModel {
  @PrimaryGeneratedColumn() // 자동으로 id값을 하나씩 증가시켜줌
  id: number;

  @Column()
  author: string;

  @Column()
  title: string;

  @Column()
  content: string;

  @Column()
  likeCount: number;

  @Column()
  commentCount: number;
}

Repository 주입하기

  constructor(
    @InjectRepository(PostsModel)
    private readonly postsRepository: Repository<PostsModel>,
  ) {}

Find 함수 사용해서 다수의 데이터 가져오기

  async getAllPosts() {
    this.postsRepository.find(); // 모든 데이터를 가져옴, postsRepository의 함수는 전부 다 비동기(async를 지정해줘야함)
  }

FindOne 함수 이용해서 하나의 데이터만 찾기

  async getPostById(id: number) {
    const post = await this.postsRepository.findOne({
      where: {
        id,
      },
    });

    // await을 하지않으면 여기서 에러가 잡히지 않음 -> Promise로 반환되기에 null이 아님
    if (!post) {
      throw new NotFoundException();
    }
    return post;
  }

Create 함수로 새로운 데이터 생성하기

  async createPost(author: string, title: string, content: string) {
    // 1. create : 저장할 객체를 생성한다
    // 2. save : 객체를 저장한다. (create매서드에서 생성한 객체를 저장함)

    // create는 실제로 DB에 저장하는것이 아니고 객체만 생성하는것이기에 await을 안해도 됨 (동기로 동작함)
    const post = this.postsRepository.create({
      // id는 DB에서 생성을 해줌
      author,
      title,
      content,
      likeCount: 0,
      commentCount: 0,
    });
    const newPost = await this.postsRepository.save(post);

    // 응답은 새로 만든 post만 반환한다.
    // 허용되는 정보 안에서 최소한의 데이터를 반환해주는것이 가장 좋다.
    // 최소한의 정보를 주되, 꼭 필요한 정보는 모두 담아서 반환을 해줘야함.
    // 이유 : 서버를 클라우드에 올리면 데이터를 얼마나 보냈냐에 따라서 과금을 함.
    return newPost; // (201 Created)
  }

Save 함수로 업데이트 하기

  async updatePost(
    postId: number,
    author?: string,
    title?: string,
    content?: string,
  ) {
    // save의 기능
    // 1) 만약 데이터가 존재하지 않는다면 (id기준으로) 새로 생성한다
    // 2) 만약 데이터가 존재한다면 (같은 id 값이 존재) 존재하던 값을 업데이트 한다

    const post = await this.postsRepository.findOne({
      where: {
        id: postId,
      },
    });

    if (!post) {
      throw new NotFoundException();
    }
    if (author) {
      post.author = author;
    }
    if (title) {
      post.title = title;
    }
    if (content) {
      post.content = content;
    }

    const newPost = await this.postsRepository.save(post);

    return newPost;
  }

Delete 함수로 데이터 삭제하기

  async deletePost(postId: number) {
    const post = await this.postsRepository.findOne({
      where: {
        id: postId,
      },
    });
    // id가 없다면 NotFoundException를 던지는 로직
    if (!post) {
      throw new NotFoundException();
    }
    // id가 있으면 posts에 필터해서 삭제함
    await this.postsRepository.delete(postId);
    // 삭제한 포스트의 id를 반환함
    return postId;
  }
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유