export class BaseEntity {
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
@VersionColumn()
version: number;
}
@Entity()
export class Movie {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
genre: string;
@Column(() => BaseEntity)
base: BaseEntity;
}
내가 설정한 객체에 임베딩 (extend와의 차이)
@Entity()
export class Movie extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
genre: string;
}
일반적인 상속 방법으로 사용
@Entity()
@TableInheritance({
column: {
name: 'type',
type: 'varchar',
},
})
export class Content extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
genre: string;
}
@ChildEntity()
export class Movie extends Content {
@Column()
runtime: number;
}
@ChildEntity()
export class Series extends Content {
@Column()
seriesCount: number;
}
childEntity에서의 개별적인 컬럼들을 포함하여 하나의 테이블로 생성.
이 때 개별적인 값들은 nullable 인데 로우 생성 시 content테이블에는 다음과 같이 생성된다.
post movie -> seriesCount는 null로 생성
post series -> runtime은 null로 생성
근데 언제 써야할지는 잘 모르겠다..
대신 SQL로 만드는 건 감도잘 안오는데 굉장히 직관적으로 구현할 수 있는 것 같다
async createMovie(createMovieDto: CreateMovieDto) {
const movieDetail = await this.movieDetailRepository.save({
detail: createMovieDto.detail,
});
const movie = await this.movieRepository.save({
title: createMovieDto.title,
genre: createMovieDto.genre,
detail: movieDetail,
});
return movie;
}
기존 영화 생성코드인데 사실 movieDetail 을 따로 선언해서 사용하지않고 바로
detail: createMovieDto.detail을 할 수 있으면 편하다.
그러나 바로 아래와 바로 써버리면 영화 조회시에 detailId가 null이고 연결이 안된다.
async createMovie(createMovieDto: CreateMovieDto) {
const movie = await this.movieRepository.save({
title: createMovieDto.title,
genre: createMovieDto.genre,
detail: {
detail: createMovieDto.detail,
},
});
return movie;
}
이것을 가능하게 하는 것이 cascade 옵션이다.
@OneToOne(() => MovieDetail, (movieDetail) => movieDetail.id, {
cascade: true,
})
Movie Entity에서 relationship 관련 부분에
cascade를 true로 해주면 movie생성시에 detail 테이블까지 한꺼번에 생성가능하다.