[TypeORM] entity 작성하기

21214 단어 typeOrmtypeOrm

개요

팀 프로젝트 회의를 하면서 작성한 ERD의 일부를 TypeORM을 이용해 entity를 작성해볼 예정이다.👏👏

ERD관계

USER(1) <-> PARENT(1) -> 일대일 관계
USER(1) <-> BABYSITTER -> 일대일 관계

  • forein key는 parent, babysitter쪽에 user_id로 생성할 예정입니다.

기본적인 데코레이션들

@PrimaryGeneratedColumn

  • 이름 그대로 PK를 생성해주는 데코레이션이다.
  • autoIncrement가 적용된 데코레이션이다.

@PrimaryColumn

  • PK를 생성해주지만 autoIncrement는 지원하지 않는 데코레이션이다.

@Column

  • 역시 이름 그대로 column을 생성할 때 기본으로 사용되는 데코레이션이다.

다양한 column option, type

@Column("int")
or 
@Column({ type: "int" })

// 길이를 200으로 제한한다.
@Column("varchar", { length: 200 })

// not null 옵션과 데이터 타입을 number로 설정한다.
@Column({nullable : false})
    code: number;
  • TypeORM은 DB에서 지원하는 데이터 타입은 다 지원을 하고 이에 더해 json, list 등 다양한 타입을 지원한다. 자세한 내용은 공식문서를 보면 매우 많이 정보를 확인할 수 있다.

연관관계 설정하기

OneToOne 관계

// Babysitter.ts
@OneToOne(() => User, {onDelete: 'CASCADE' })
@JoinColumn()
user_id: User

babysitter와 user는 일대일 관계이고 foreign key는 babysitter에 생성되는 코드이다.

  • @OneToOne을 통해 일대일 관계라는것을 명시해주면서, 어느 엔티티와 관계가 있는지 명시해준다.
  • onDelete는 넣어도 되고 안넣어도 되는 옵션이다.
  • @JoinColumn을 통해 foreign key를 생성한다.
  • 나는 양방향 연관관계는 필요 없어서 작성을 안했지만 필요하다면 User.ts에도 @OneToOne을 명시해주면 된다.

OneToMany, ManyToOne 관계

  • 해당 관계에서는 @JoinColumn은 생략 가능합니다.
  • @OneToMany@ManyToOne이 필요하지만 역은 해당되지 않습니다.
// User.ts
// user(1) <-> parent(N)
@OneToMany(
    type => Parent, 
    parent => parent.user, { nullable: false, onDelete: 'CASCADE' }
)
parent : Parent[]
// parent.ts
@ManyToOne(
    type => User, 
    user => user.babySitter, { nullable: false, onDelete: 'CASCADE' }
    )
user : User

ManyToMany 관계

  • @JoinTalbe이 반드시 필요합니다
  • @JoinTable은 관계의 한쪽(소유) 쪽에 넣어야 합니다.
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

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

    @Column()
    name: string;
}
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(() => Category)
    @JoinTable()
    categories: Category[];
}
+-------------+--------------+----------------------------+
|                        category                         |
+-------------+--------------+----------------------------+
| id          | int(11)      | PRIMARY KEY AUTO_INCREMENT |
| name        | varchar(255) |                            |
+-------------+--------------+----------------------------+

+-------------+--------------+----------------------------+
|                        question                         |
+-------------+--------------+----------------------------+
| id          | int(11)      | PRIMARY KEY AUTO_INCREMENT |
| title       | varchar(255) |                            |
| text        | varchar(255) |                            |
+-------------+--------------+----------------------------+

+-------------+--------------+----------------------------+
|              question_categories_category               |
+-------------+--------------+----------------------------+
| questionId  | int(11)      | PRIMARY KEY FOREIGN KEY    |
| categoryId  | int(11)      | PRIMARY KEY FOREIGN KEY    |
+-------------+--------------+----------------------------+

ManyToMany 코드만 공식문서에 있는 코드입니다.

Entity작성하기

// entity/User.ts
import {Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, Timestamp} from "typeorm";

@Entity()
export class User {
    @PrimaryGeneratedColumn()
    id: number;

    @Column({nullable : false})
    email: string;

    @Column({nullable : false})
    username: string;

    @Column({nullable : false})
    nickname: string;

    @Column({nullable : false})
    password: string;

    @Column({nullable : false})
    code: number;

    @CreateDateColumn({
        
    })
    createdAt: Timestamp

}

@CreateDateColumn

  • 데이터가 생성된 시간 정보를 자동으로 생성해주는 데코레이션이다. 유용하게 사용할 데코레이션인 거 같다!
  • 이 외에도 @UpdateDateColumn, @DeleteDateColumn, @VersionColumn 가 있다.
  • 위와 같은 데코레이션 설명 역시 공식문서를 참고하면 된다.
// BabySitter.ts
import {Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, Timestamp, ManyToOne, OneToMany, OneToOne, JoinColumn} from "typeorm";
import {User} from './User';
import {Mapping} from './Mapping'

@Entity()
export class BabySitter {

    @PrimaryGeneratedColumn()
    id: number;

    @Column({nullable : false})
    age: number;

    @Column({nullable : false})
    gender: string;

    @Column({nullable : false})
    region: string;

    @Column({nullable : false})
    career: string;


    @CreateDateColumn({})
    createdAt: Timestamp

    // babysitter(N) <->  user(1)
    // @ManyToOne(
    //     type => User, 
    //     user => user.babySitter, { nullable: false, onDelete: 'CASCADE' }
    //     )
    // user! : User

  @OneToOne(() => User, {onDelete: 'CASCADE' })
    @JoinColumn()
    user_id: User

    // babysitter(1) <->  user(N)
    @OneToMany(
        type => Mapping,
        mapping => mapping.babySitter,{ nullable: false, onDelete: 'CASCADE' }
    )
    mapping: Mapping

}

마무리

  • ORM은 이번 프로젝트를 하면서 처음 사용해보는데 아직 익숙하지 않아서 그런지 조금 불편하지만 나름 재밌다.
  • 다음에는 TypeORM에 active record패턴과 data mapper패턴이 있는데 이에 대해서 공부해볼 예정이다!

🙋‍♂️🙋‍♂️🙋‍♂️

좋은 웹페이지 즐겨찾기