본문 바로가기
프로그래밍/TypeORM

[TypeORM] Eager and Lazy Relations

by YuminK 2023. 8. 31.

https://orkhan.gitbook.io/typeorm/docs/eager-and-lazy-relations

 

Eager relations

즉시 관계는 엔티티를 로드할 때 마다 자동으로 같이 로드된다.

 

import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm"
import { Question } from "./Question"

@Entity()
export class Category {
    @PrimaryGeneratedColumn()
    id: number

    @Column()
    name: string

    @ManyToMany((type) => Question, (question) => question.categories)
    questions: Question[]
}

 

import {
    Entity,
    PrimaryGeneratedColumn,
    Column,
    ManyToMany,
    JoinTable,
} from "typeorm"
import { Category } from "./Category"

@Entity()
export class Question {
    @PrimaryGeneratedColumn()
    id: number

    @Column()
    title: string

    @Column()
    text: string

    @ManyToMany((type) => Category, (category) => category.questions, {
        eager: true,
    })
    @JoinTable()
    categories: Category[]
}

 

Question을 로드할 때, join을 사용하거나 relations를 처리할 필요가 없다. 자동으로 로드 된다.

 

const questionRepository = dataSource.getRepository(Question)

// questions will be loaded with its categories
const questions = await questionRepository.find()

 

즉시 관계는 오직 find* 메소드를 사용할 때 동작한다. 쿼리빌더 즉시 관계가 disabled되어 있고 LeftJoinAndSelect를 사용해야 하는 경우, 즉시 관계는 관계의 한쪽에서만 사용될 수 있다. eager: true를 양쪽에서 사용하는 것은 금지되어 있다.

// 순환참조되지 않도록 주의하라는 이야기로 보인다.

 

Lazy relations

게으른 관계는 한번 데이터에 접근할 때 로드된다. 이러한 관계는 Promise타입을 사용해야 한다. 데이터에 접근할 때, Promise로 선언된 데이터가 반환된다.

 

import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm"
import { Question } from "./Question"

@Entity()
export class Category {
    @PrimaryGeneratedColumn()
    id: number

    @Column()
    name: string

    @ManyToMany((type) => Question, (question) => question.categories)
    questions: Promise<Question[]>
}

 

import {
    Entity,
    PrimaryGeneratedColumn,
    Column,
    ManyToMany,
    JoinTable,
} from "typeorm"
import { Category } from "./Category"

@Entity()
export class Question {
    @PrimaryGeneratedColumn()
    id: number

    @Column()
    title: string

    @Column()
    text: string

    @ManyToMany((type) => Category, (category) => category.questions)
    @JoinTable()
    categories: Promise<Category[]>
}

 

Categories는 Promise로 되어 있다. 이는 lazy이며, 오직 promise로 저장된다.

 

저장예시

const category1 = new Category()
category1.name = "animals"
await dataSource.manager.save(category1)

const category2 = new Category()
category2.name = "zoo"
await dataSource.manager.save(category2)

const question = new Question()
question.categories = Promise.resolve([category1, category2])
await dataSource.manager.save(question)

 

게으른 관계 예시 

const [question] = await dataSource.getRepository(Question).find()
const categories = await question.categories
// you'll have all question's categories inside "categories" variable now

 

만약 다른 언어를 사용하며(Java, PHP 등) 게으른 관계를 어디에나 사용했다면, 주의해라. 이러한 언어들은 비동기적이지 않으며 다른 방식으로 동작한다. 이것이 타 언어에서 Promise를 사용하지 않은 이유다. 

 

자바스크립트와 Node.js에서는 게으른 관계를 사용하기 위해 Promise를 써야 한다.

이는 비표준 기술이며 TypeORM에서 실험적으로 여겨진다.

 

// TypeORM 문서에 따르면 기본적인 개념 자체(Eager, Lazy)는 동일하나 다른 언어에서 구현된 형태와 다르다고 한다.

// TypeORM은 JPA와 다르게 기본적으로 Lazy, Eager 옵션을 설정하지 않으니, 명시적으로 QueryBuilder 혹은 FindOption을 사용하여 처리하는 것을 기본으로 생각하면 좋을 것 같다.

'프로그래밍 > TypeORM' 카테고리의 다른 글

[TypeORM] Entity Inheritance  (0) 2023.08.31
[TypeORM] Embedded Entities  (0) 2023.08.31
[TypeORM] What is EntityManager and Repository  (0) 2023.08.31
[TypeORM] Working with DataSource  (0) 2023.08.30
[TypeORM] DataSource API  (0) 2023.08.30

댓글