[코팩] NestJs typeORM + DB 를 사용한 CRUD

Seong Hyeon Kim·2024년 2월 22일
0

NestJs

목록 보기
11/14

1. Get (게시물 전제조회 하기)

기존에 사용되었던 getAllpost 에 기존 내용을 지워주시고 this.postRepositody. 까지만 입력하면 사진처럼 무수히 많은 기능들을 가진 api들을 사용할 수 있는것을 확인할 수 있습니다.

여기서 지금 사용할것은 find() 입니다

  async getAllPosts() {
    this.postRepository.find();
  }

기존에 작성된 posts 만을 불러오던 내용에서 find() 를 사용해서 DB 의 모든 내용을 불러오는 코드로 변경하였습니다. 그리고 참고로 여기서 사용되는 api 들은 전부 비동기 이기 지금 작성한 전체조회를 위한 코드에서는 사용될 일이 없겠지만 동기적인 작업이 필요한 상황을 대비해 미리 async 를 작성해두는게 좋을 것 같습니다.



2. Get (한개의 게시물만 조회하기)

  async getPostById(id: number) {
    return this.postRepository.findOne({
      where: {
        id:id,
      },
    })
  }

마찬가지로 기존 코드에서 이번에는 findOne() 을 사용해서 변경된 코드입니다.

이때 기존코드에서도 입력받은 id 값이 일치한 것만 찾는다 라는 방식과 동일하게 SQL 문에서 사용된것과 동일한 where문을 사용해서 찾고자 하는 게시물의 id 값이 입력받은 id 값과 같은것만을 찾는 형태의 조건문 형태로 Get 요청을 하는 것을 볼 수 있습니다.

포스트맨에서 실행해도 여전히 요청은 성공적으로 작동하지만 데이터가 없기 때문에 아무런 값도 반환하지 않는것을 볼 수 있습니다.

그래서 기존에 했었던 것과 동일하게 값이 없었을때에의 에러핸들링을 작성해주도록 하겠습니다.

  async getPostById(id: number) {
    const post = await this.postRepository.findOne({
      where: {
        id: id,
      },
    });
    
    if(!post){
      throw new NotFoundException();
    }
    
    return post
  }

앞서 설명드렸던 것처럼 postRepository로 불러오는 api 요청들은 모두 비동기처리기 때문에 여기서는 await 을 붙여주지 않으면 다음 문맥인 if 문에서 에러가 잡히지 않습니다.

그래서 반드시 await 을 붙여주고 기존에 했던 것과 동일하게 NotFoundException() 를 사용해주면 기존과 동일하게 데이터 없을때에는 없다라고 나오게 처리되는것을 볼 수 있습니다.



3. Post (게시물 작성하기)

조회만 계속했기 때문에 이번엔 생성하기도 변경해보겠습니다.

전체 코드는 다음과 같습니다.

async createPost(author: string, title: string, content: string) {
    // 1) create method -> 저장할 객체를 생성한다.
    // 2) save method -> 객체를 저장한다. (create 메서드에서 생성한 객체로)
    
    const post = this.postRepository.create({
      author,
      title,
      content,
      likeCount:0,
      commentCount:0,
    });
    
    const newPost = await this.postRepository.save(post)

    return newPost;

  }

코드 주석에 작성되어있듯이 새로운 객체를 생성하고 그 객체를 저장한다 의 순서로 진행될 예정입니다.

실제로 create() 는 생성만 하고 그래서 비동기가 아니라 동기로 이루어집니다.
그래서 create를 선언한 후 객체안에 기존처럼 만들고자 하던 값을 만들어서 새롭게 작성이 될 새로운 객체를 만들어서 post 라는 변수에 저장해줍니다.

그리고 newPost 를 선언한 후 저장을 할텐데, 이때 위에서 작성된 post 와 newPost 차이점중 하나는 post 에는 id값이 없습니다. id 값은 DB 에서 자동으로 생성될 예정이기 때문입니다.

결국 새롭게 만든 객체를 기존에 있던 DB에 저장하되 id값까지 추가된 값으로 저장하는 부분이 newPost 라고 보면 되겠습니다.

포스트맨으로 실행한 결과에서도 id 값이 잘 추가된 형태로 나오는 것도 확인할 수 있습니다.


그리고 아까는 값이 없어서 나오지 않던 전체조회나 게시물 조회도 이제는 잘 나오는것도 확인할 수 있습니다.

이로써 기존에는 메모리에 저장하던 값들을 드디어 DB에 저장하는 형태로 완전히 전환이 된 것입니다.



4. Updadate (게시물 변경하기)

async updatePost(postId: number, author: string, title: string, content: string) {
    // save의 기능
    // 1) 만약 데이터가 없다면 (id 기준으로) 새롭게 생성한다.
    // 2) 만약 데이터가 존재한다면( id 기준으로 ) 존재하던 값을 변경(업데이트) 한다.
    
    const post = await this.postRepository.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.postRepository.save(post)

    return newPost;
  }

create 에서도 적어놓았던 부분이지만 한번 더 강조하자면 save의 특징에 대해서 한번더 서술하면, 다음과 같습니다.

1) 만약 데이터가 없다면 (id 기준으로) 새롭게 생성한다.
2) 만약 데이터가 존재한다면( id 기준으로 ) 존재하던 값을 변경(업데이트) 한다.

실제로 마우스를 올려보면 같은 내용이 설명에 있는것을 확인할 수 있습니다.

그렇기 때문에 기존에 사용되었던 코드를 id 를 찾는식인 findOne() 을 사용해서 id 값이 있는 post 를 찾고 입력받은 값들로 변경해서 새롭게 저장하는 형태의 코드로 변경하면 간단하게 완성입니다.

포스트맨으로도 잘 되는것을 확인할 수 있습니다.



5. Delete (게시물 삭제하기)

 async deletePost(postId: number) {
    const post = await this.postRepository.findOne({
      where: {
        id: postId,
      }
    })

    if (!post) {
      throw new NotFoundException();
    }

    await this.postRepository.delete(post)
    
    return `선택하신 ${postId}번 게시물이 삭제되었습니다`;
    
  }

update 와 동일하게 id값이 일치하는 post 를 찾고 delte() 를 사용해서 제거해주면 됩니다.


profile
삽질도 100번 하면 요령이 생긴다. 부족한 건 경험으로 채우는 백엔드 개발자

0개의 댓글