일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- restful api
- component
- SWIFT
- Nest.js
- props
- file upload
- state
- back-end
- vue
- 개발이 취미인 사람
- spring boot
- java
- 개발자
- Kotlin
- AWS
- javascript
- 반복문
- 자바
- 상속
- 조건문
- 코틀린
- It
- node.js
- swagger
- react
- Producer
- front-end
- kafka
- class
- Sequelize
- Today
- Total
개발이 취미인 사람
[Nest.js] Nest.js API 만들기 (7) - TypeORM 관계 설정(1 : 1, 1 : N, N : M) 본문
[Nest.js] Nest.js API 만들기 (7) - TypeORM 관계 설정(1 : 1, 1 : N, N : M)
RyanSin 2021. 11. 14. 17:02- 지난 시간
안녕하세요. 지난 시간에는 TypeORM을 적용해 API 서버를 수정하는 시간은 가져봤습니다.
혹시 지난 시간 내용을 놓치고 오신 분들은 아래 링크를 통해 학습하고 오시는 걸 추천드리겠습니다.
[Nest.js] Nest.js API 만들기 (6) - TypeORM API서버 적용(CRUD)
- 개요
이번 시간에는 TypeORM에서 관계 설정하는 방법에 대해 알아보겠습니다.
보통 관계를 맺는 방식은 1 : 1(일 대 일), 1 : M (일 대 다), N : M (다 대 다)로 맺습니다.
관계 설정시 사용되는 데코레이터는 @OneToOne, @OneToMany, @ManyToOne , @ManyToMany 가 사용됩니다.
1 : 1 관계 설정(User Entity & Profile Entity)
User Entity
import {
BaseEntity,
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
Unique,
OneToOne,
JoinColumn,
} from 'typeorm';
import { Profile } from './profile.entity';
@Entity({ name: 'user' })
@Unique(['user_id'])
export class User extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ type: 'varchar', length: 50, comment: '유저 아이디' })
user_id: string;
@Column({ type: 'varchar', length: 255, comment: '유저 비밀번호' })
password: string;
@Column({ type: 'varchar', length: 255, comment: 'salt' })
salt: string;
@Column({ type: 'varchar', length: 30, comment: '유저 이름' })
name: string;
@Column({ type: 'tinyint', comment: '유저 나이' })
age: number;
@CreateDateColumn({ name: 'create_at', comment: '생성일' })
createdAt: Date;
@UpdateDateColumn({ name: 'update_at', comment: '수정일' })
updatedAt: Date;
@DeleteDateColumn({ name: 'delete_at', comment: '삭제일' })
deletedAt?: Date | null;
/**
* 1 : 1 관계 설정
* @OneToOne -> 해당 엔티티(User) To 대상 엔티티(Profile)
* 하나의 유저는 하나의 개인정보를 갖는다.
*/
@OneToOne(() => Profile)
@JoinColumn({ name: 'profile_id' })
profile: Profile;
}
Profile Entity
//Enum 설정
enum STATUS {
PAUSE = 'PAUSE',
ACTIVE = 'ACTIVE',
}
import {
BaseEntity,
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
} from 'typeorm';
@Entity({ name: 'profile' })
export class Profile extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({
type: 'varchar',
length: 50,
comment: '유저 권한(Ex: 관리자, 일반 유저 등등)',
})
permission: string;
@Column({
type: 'enum',
enum: STATUS,
default: STATUS.PAUSE,
comment: '계정상태(ACTIVE, PAUSE)',
})
status: string;
@Column({ type: 'tinyint', width: 1, default: 0, comment: '계정 블락 유무' })
block: string;
@Column({
type: 'date',
comment: '계정 유효기간(패키지 별 설정) Ex) 2021-12-14',
})
account_expired: Date;
@Column({
type: 'date',
comment: '비밀번호 유효기간(주기적 업데이트) Ex) 2021-12-14',
})
password_expired: Date;
@CreateDateColumn({ name: 'create_at', comment: '생성일' })
createdAt: Date;
@UpdateDateColumn({ name: 'update_at', comment: '수정일' })
updatedAt: Date;
@DeleteDateColumn({ name: 'delete_at', comment: '삭제일' })
deletedAt?: Date | null;
}
두 Entity는 1 : 1 관계를 설정했습니다. User Entity에서 @OneToOne 데코레이터와 @JoinColumn 데코레이터를 확인할 수 있습니다.
@OneToOne 데코레이터는 말 그대로 대상 Entity(Profile)와 1 : 1 관계를 설정이며, @JoinColumn 데코레이터는 대상 Entity(Profile) 고유 아이디 값을 FK(foreign key:외래키)로 설정한다는 뜻입니다.
1 : N 관계 설정 (User Entity & CompanyInformation Entity)
User Entity
import {
BaseEntity,
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
Unique,
OneToOne,
JoinColumn,
ManyToOne,
} from 'typeorm';
import { CompanyInformation } from './company_infomation.entity';
import { Profile } from './profile.entity';
@Entity({ name: 'user' })
@Unique(['user_id'])
export class User extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ type: 'varchar', length: 50, comment: '유저 아이디' })
user_id: string;
@Column({ type: 'varchar', length: 255, comment: '유저 비밀번호' })
password: string;
@Column({ type: 'varchar', length: 255, comment: 'salt' })
salt: string;
@Column({ type: 'varchar', length: 30, comment: '유저 이름' })
name: string;
@Column({ type: 'tinyint', comment: '유저 나이' })
age: number;
@CreateDateColumn({ name: 'create_at', comment: '생성일' })
createdAt: Date;
@UpdateDateColumn({ name: 'update_at', comment: '수정일' })
updatedAt: Date;
@DeleteDateColumn({ name: 'delete_at', comment: '삭제일' })
deletedAt?: Date | null;
/**
* 1 : 1 관계 설정
* @OneToOne -> 해당 엔티티(User) To 대상 엔티티(Profile)
* 하나의 유저는 하나의 개인정보를 갖는다.
*/
@OneToOne(() => Profile)
@JoinColumn({ name: 'profile_id' })
profile: Profile;
/**
* 1 : M 관계 설정
* @ManyToOne -> 해당 엔티티(User) To 대상 엔티티(CompanyInformation)
* 여러 유저는 하나의 회사에 소속
*/
@ManyToOne(
() => CompanyInformation,
(comapnyInformation) => comapnyInformation.userId,
)
@JoinColumn({ name: 'company_id' })
companyInformation: CompanyInformation;
}
CompanyInformation Entity
import { IsEmail } from 'class-validator';
import {
BaseEntity,
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
OneToMany,
} from 'typeorm';
import { User } from './user.entity';
@Entity({ name: 'company_information' })
export class CompanyInformation extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
//length 설정하지 않으면 기본 255 길이 설정
@Column({
type: 'varchar',
comment: '회사 이름',
})
hospital_name: string;
@IsEmail()
@Column({
type: 'varchar',
length: 50,
comment: '회사 이메일',
})
email: string;
@Column({ type: 'varchar', length: 50, comment: '회사 관리자 이름' })
name: string;
@Column({
type: 'varchar',
length: 72,
comment: '회사 전화번호',
})
phone: string;
@Column({
type: 'varchar',
length: 72,
comment: '팩스번호',
})
fax: string;
@Column({
type: 'varchar',
length: 45,
name: 'business_number',
comment: '사업자등록 번호',
})
business_number: string;
@Column({
type: 'text',
comment: '주소',
})
address: string;
@Column({
type: 'text',
comment: '상세주소',
})
detail_address: string;
@CreateDateColumn({ name: 'create_at', comment: '생성일' })
createdAt: Date;
@UpdateDateColumn({ name: 'update_at', comment: '수정일' })
updatedAt: Date;
@DeleteDateColumn({ name: 'delete_at', comment: '삭제일' })
deletedAt?: Date | null;
/**
* 1 : M 관계 설정
* @OneToMany -> 해당 엔티티(CompanyInformation) To 대상 엔티티 (User)
*/
@OneToMany(() => User, (user) => user.id)
userId: User[];
}
1 : N 관계를 설정할 때 @OneToMany & @ManyToMany라고 위에서 말씀드렸습니다.
하나의 회사는 여러 임직원을 둘 수 있습니다. 그렇기 때문에 CompanyInformation Entity에는 @OneToMany 데코레이터로 설정을 했으며, User Entity는 여러 대상이 될 수 있기 때문에 @ManyToOne으로 설정했습니다.
User Entity는 특정 회사에 소속되기 때문에 @JoinColumn 데코레이터를 사용해 CompanyInformation에 외례키를 갖습니다
N : M 관계 설정(Borad Entity & Category Entity)
Board Entity
import {
BaseEntity,
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
ManyToMany,
JoinTable,
} from 'typeorm';
import { Category } from './category.entity';
@Entity({ name: 'board' })
export class Board extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
//length 설정하지 않으면 기본 255 길이 설정
@Column({
type: 'varchar',
comment: '게시글 이름',
})
name: string;
@Column({
type: 'varchar',
length: 4000,
comment: '게시글 내용',
})
content: string;
@Column({
type: 'int',
default: 0,
comment: '게시글 조회수',
})
view: number;
@CreateDateColumn({ name: 'create_at', comment: '생성일' })
createdAt: Date;
@UpdateDateColumn({ name: 'update_at', comment: '수정일' })
updatedAt: Date;
@DeleteDateColumn({ name: 'delete_at', comment: '삭제일' })
deletedAt?: Date | null;
@ManyToMany(() => Category)
@JoinTable()
category: Category;
}
Category Entity
import {
BaseEntity,
Column,
Entity,
PrimaryGeneratedColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
} from 'typeorm';
@Entity({ name: 'category' })
export class Category extends BaseEntity {
@PrimaryGeneratedColumn('uuid')
id: string;
//length 설정하지 않으면 기본 255 길이 설정
@Column({
type: 'varchar',
comment: '카테고리 이름',
})
name: string;
@CreateDateColumn({ name: 'create_at', comment: '생성일' })
createdAt: Date;
@UpdateDateColumn({ name: 'update_at', comment: '수정일' })
updatedAt: Date;
@DeleteDateColumn({ name: 'delete_at', comment: '삭제일' })
deletedAt?: Date | null;
}
N : M(다 대 다 ) 관계를 설정 할 때는 @ManyToMany 데코레이터를 사용합니다.
두 Entity를 선언하면 두 Entity를 연결해주는 Entity가 생성이 됩니다. (board_category_category)
게시글은 여러 카테고리에 소속 될 수 있기 때문에 Category 배열로 속성을 갖습니다.
위 Entity를 확인하면 FK(foreign key:외래키)를 board_category_category 테이블에게 위임한 걸 알 수 있습니다.
이번 시간에는 TypeORM에서 관계 설정에 대해 알아봤습니다.
궁금한 사항은 댓글을 남겨주시면 감사하겠습니다. :)
소스 저장소
github: https://github.com/Ryan-Sin/Node_Nest/tree/v6