One to One은 일대일 관계를 정의한다.
한 엔터티가 다른 엔터티를 가질 때 사용된다.
예를 들어, profile과 user 엔터티가 서로 일대일 관계를 가진다고 설정하겠다.
// profile.entity.ts
@Entity()
export class ProfileModel {
@PrimaryGeneratedColumn()
id: number;
@OneToOne(()=> UserModel, (user)=> user.profile)
@JoinColumn()
user: UserModel;
@Column()
profileImg: string;
}
// user.entity.ts
@OneToOne(()=> ProfileModel, (profile)=> profile.user)
profile: ProfileModel
() => UserModel은 관계 대상인 UserModel을 가리킨다.
(user) => user.profile는 관계의 반대측 엔터티에서 역참조할 때 사용된다.
즉, UserModel 엔터티 내에서 profile이라는 속성을 통해 다른 엔터티(이 예제에서는 Profile)에 접근할 수 있게 한다.
@JoinColumn(): 이 데코레이터는 데이터베이스 테이블의 컬럼을 나타낸다.
이 경우, UserModel과 Profile 사이의 관계를 위한 외래 키를 가리키는 컬럼을 만들게 된다.
// Controller
@Post('user/profile')
async createUserAndProfile() {
const user = await this.userRepository.save({
email: 'grie2manna717@gmail.com',
})
const profile = await this.profileRepository.save({
profileImg: 'asdf.jpg',
user
})
return user;
}
이렇게 컨트롤러도 지정해줬다.
@ ManyToOne : 다대일 관계를 정의한다.
예를 들어, 여러 개의 엔터티가 하나의 다른 엔터티를 참조할 때 사용된다.
@ OneToMany : 일대다 관계를 정의한다.
여러 엔터티가 한 개의 다른 엔터티를 가질 때 사용된다.
이는 주로 @ManyToOne과 함께 사용된다.
예를 들어, Post와 User의 엔티티를 서로 관계를 만드려고 한다.
// PostModel
@Entity()
export class PostModel {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(()=> UserModel, (user) => user.posts)
author: UserModel;
@Column()
title: string
}
// user.entity.ts
@OneToMany(()=> PostModel, (post)=> post.author)
posts: PostModel[];
}
포스트에 대해 작성자를 userModel을 받아오게 하고 그걸 유저가 포스트를 작성한 것을 표현한다.
// Controller
@Post('user/post')
async createUserAndPosts() {
const user = await this.userRepository.save({
email : 'postuser@gmail.com',
});
await this.postRepository.save({
author: user,
title: 'post 1',
})
await this.postRepository.save({
author: user,
title: 'post 2',
})
return user;
}
}
이렇게 컨트롤러도 지정해줬다.
다대다 관계를 정의한다.
여러 엔터티가 서로 많은 다른 엔터티와 연결되어 있을 때 사용된다.
예를 들어, post와 tag로 엔티티를 구성해보겠다. 하나의 포스트에는 여러 태그가 달릴 수 있고 하나의 태그에도 여러 포스트가 적용될 수 있다.
// tag
@Entity()
export class TagModel {
@PrimaryGeneratedColumn()
id: number;
@ManyToMany(()=> PostModel, (post)=> post.tags)
posts: PostModel[];
@Column()
name: string;
}
// post
@ManyToMany(()=> TagModel, (tag)=> tag.posts)
@JoinTable()
tags: TagModel[];
}
@ManytoMany를 사용해 서로 관계를 만들어줬다.
// Controller
@Post('posts/tags')
async createPostTags() {
const post1 = await this.postRepository.save({
title: 'Nest JS',
});
const post2 = await this.postRepository.save({
title: 'Programming',
});
const tag1 = await this.tagRepository.save({
name: 'Javascript',
posts:[post1, post2],
});
const tag2 = await this.tagRepository.save({
name: 'TypeScript',
posts:[post1],
});
const post3 = await this.postRepository.save({
title: 'NextJS',
tags:[tag1, tag2],
});
return true;
}
@Get('posts')
getPosts() {
return this.postRepository.find({
relations: {
tags: true,
}
});
}
@Get('tags')
getTags() {
return this.tagRepository.find({
relations: {
posts: true,
}
})
}
}
컨트롤러를 만들어 태그와 게시물을 서로 관계를 만들어줬으며 이를 get으로 들어가면 각자 태그와 포스트가 보이게 컨트롤러를 작성했다.