728x90

어떤 관계들이 존재하는지에 대해서는 생략하고, 바로 OneToMany와 ManyToOne의 관계에 대해서 알아보자.

 

여기서는 사용자와 해당 사용자가 작성하는 보고서에 대한 관계로 설명을 해보려고 한다.

 

우선 OneToMany 관계이다.

한명의 사용자가 많은 양의 보고서를 작성할거기에 One이 사용자, Many가 보고서이다.

따라서 OneToMany는 User 쪽에 작성하는 데코레이션이다.

 

    @OneToMany(() => Report, (report) => report.users)
    reports: Report[];

 

@OneToMany로 2가지의 파라미터를 넘긴다.

우선 첫번째 파라미터는 Many 쪽의 타입이다.

Many로 가져올 타입을 명시하며, () => Report 처럼 함수형으로 반환하는 이유는 곧 보겠지만

Report 쪽에도 이렇게 Users 타입을 주게 되는데, 이 때 두 Entity 간에 순환 참조 에러가 발생하게 된다.

그렇기에 함수의 리턴타입으로 명시해주는 것이다.

 

그리고 2번째 파라미터는, Many 쪽에서 해당 Entity를 가지고 있는 property다.

지금은 하나밖에 없어서 그냥 users로 명시하고 있지만

 

만약 updateUser가 추가된다면

    @OneToMany(() => Report, (report) => report.updatedUser)
    updateReports: Report[];

이렇게 updateUser와 같은 속성을 명시해주는 것이다.

 

이런 이유로 OneToMany에도 2가지의 파라미터를 더 넘기게 된다.

 

이제 Many쪽으로 넘어가보자.

    @ManyToOne(() => Users, (Users) => Users.reports)
    users: Users

Many쪽도 다음과 같은 이유로 2개의 파라미터를 작성한다.

 

그리고 이렇게 작성을 하면 Many 쪽에는

다음과 같이 user쪽의 PK를 가지는 column이 추가된다.

 

근데 여기서 다음과 같은 문제가 발생한다.

우선 지금과 같이 작성해서는

    @Get("/check")
    @UseGuards(AuthGuard)
    async checkLogin(@Authentication() authentication: Users): Promise<Users>{
        console.log(authentication.reports)
        return authentication
    }

해당 코드에서 undefined가 출력되게 된다.

OneToMany 관계에서 Many를 불러오지 못하는 것이다.

 

불러오기 위해서는 다음과 같이 eager:true를 설정해줘야 한다.

@OneToMany(() => Report, (report) => report.users, {
        eager: true
    })
    reports: Report[];

이러면 출력은 된다.

 

하지만 또 문제가 발생한다.

이러면 로그인만 하더라도 모든 report까지 조회하게 된다.

로그인을 하면 user entity를 조회하게 될텐데, 그 때마다 report를 조회한다면 큰 오버헤드 일 것이다.

 

그렇기에 필요할 때만 가져오도록 만들어야 한다.

그러기 위해서는 해당 property를 다음과 같이 수정한다.

    @OneToMany(() => Report, (report) => report.users, {
        lazy: true
    })
    reports: Promise<Report[]>;

이렇게 타입을 Promise로 설정하고, lazy를 true로 하면 해당 property를 사용하려고 할 때 다시 쿼리를 날려서 report를 조회해온다.

 

테스트로 다음과 같이 코드를 작성하고 실행하면

    @Get("/check")
    @UseGuards(AuthGuard)
    async checkLogin(@Authentication() authentication: Users): Promise<Users>{
        console.log("before query")

        console.log(await authentication.reports)
        return authentication
    }

 

로그가 출력되고 그 다음에 다시 쿼리를 날리는 것을 볼 수 있다.

 

이 외에도 다양한 방법의 관계에서의 설정들이 있을텐데, 꾸준하게 nest를 공부하면서 알아보도록 하자.

+ Recent posts