User를 그룹화하여 분류하고 싶다는 요청이 들어왔고 필요한 기능은 아래와 같다.
User는 여러 Group에 속할 수 있고, Group은 여러 User를 포함할 수 있으니 다대다(Many to many) 테이블로 설계하였다. 후에 다른 group 테이블이 필요할 수도 있으므로 분류하기위해 user_group이라는 테이블을 만들고, 중간 테이블은 user_group_list라고 이름 지었다.
Table 생성 방법
entity 파일 작성 -> migration:generate -> migration:run -> merge
@OneToMany, ManyToOne, ManyToMany
! @ManyToMany
를 이용하여 생성했을 때, 중간 테이블이 자동으로 만들어지는데 이때 중간 테이블인 엔티티를 불러올 수 없게되어 커스텀으로 다대다 관계를 만들어야 한다.
참고 : Many-to-Many with custom fields
/// user_group table
import { Column, Entity, OneToMany } from 'typeorm';
import { CommonEntity } from '../subtask-notices/entities/common.entity';
import { UserGroupList } from './user-group-list.entity';
@Entity({ name: 'user_groups' })
export class UserGroup extends CommonEntity {
@Column({ type: 'character varying', name: 'name', length: 20 })
name: string;
@OneToMany(() => UserGroupList, (userGroupList) => userGroupList.userGroup)
userGroupList?: UserGroupList[];
}
// user_group_list table
import { Column, Entity, JoinColumn, ManyToOne } from 'typeorm';
import { CommonEntity } from '../subtask-notices/entities/common.entity';
import { User } from '../users/user.entity';
import { UserGroup } from './user-group.entity';
@Entity({ name: 'user_group_lists' })
export class UserGroupList extends CommonEntity {
@Column({ name: 'user_group_id', type: 'bigint' })
user_group_id: number;
@ManyToOne(() => UserGroup, (userGroup) => userGroup.userGroupList)
@JoinColumn({ name: 'group_id' })
userGroup: UserGroup;
@Column({ name: 'user_id', type: 'bigint' })
user_id: number;
@ManyToOne(() => User, (user) => user.userGroupList)
@JoinColumn({ name: 'user_id' })
user: User;
}
// user entity
...
@OneToMany(() => UserGroupList, (userGroupList) => userGroupList.user)
userGroupList?: UserGroupList[];
...
migration 생성에는 두가지 방법이 있다.
yarn run typeorm migration:create -n NewMigration
{TIMESTAMP}-NewMigration.ts로 파일이 생성된다.
yarn run typeorm migration:generate -n NewMigration
create와 같이 파일이 생성되지만 다른 점이 있다면 현재 DB와 새로 생성된 entity의 모델을 비교하여 다른 부분을 자동으로 작성한다는 점이다.
이렇게 보면 압도적으로 generate가 좋아보이지만 아예 새로운 엔티티가 아닌 기존 엔티티에서 수정이 일어났을 때 (컬럼명 변경이나 타입 변경 등) 해당 테이블의 데이터를 DROP한 뒤 재생성이 이뤄지기에 데이터가 없어지게 된다고 한다. 참고
만약 위의 내용이 사실이라면 새 엔티티를 생성할 땐 generate, 기존 엔티티의 수정일 땐 create가 좋아 보인다.
yarn run typeorm migration:run
테이블이 잘 생성됐다
테이블을 확인했는데 잘못 만들어졌다면 ..
1. yarn run typeorm migration:revert
2. migration 파일 삭제
3. entity 수정
4. generate
5. Migration 수정하기
6. run