https://orkhan.gitbook.io/typeorm/docs/one-to-one-relations
OneToOne 관계는 A가 오직 하나의 B 인스턴스를 가진다.
그리고 B는 오직 하나의 A 인스턴스를 가진다.
다음 예시는 User와 Profile의 관계이다.
User는 하나의 Profile을 가지고 하나의 Profile은 하나의 User를 가진다.
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number
@Column()
gender: string
@Column()
photo: string
}
import {
Entity,
PrimaryGeneratedColumn,
Column,
OneToOne,
JoinColumn,
} from "typeorm"
import { Profile } from "./Profile"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@OneToOne(() => Profile)
@JoinColumn()
profile: Profile
}
여기 @OneToOne을 유저에게 줬고 Profile을 타겟으로 지정했다.
또한 @JoinColumn을 추가했는데 이는 관계에 한 쪽에만 추가되어야 하며 필수값이다.
@JoinColumn으로 설정하는 쪽이 외래키를 가지게 된다.
생성되는 테이블)
+-------------+--------------+----------------------------+
| profile |
+-------------+--------------+----------------------------+
| id | int(11) | PRIMARY KEY AUTO_INCREMENT |
| gender | varchar(255) | |
| photo | varchar(255) | |
+-------------+--------------+----------------------------+
+-------------+--------------+----------------------------+
| user |
+-------------+--------------+----------------------------+
| id | int(11) | PRIMARY KEY AUTO_INCREMENT |
| name | varchar(255) | |
| profileId | int(11) | FOREIGN KEY |
+-------------+--------------+----------------------------+
다시한번, @JoinColumn은 관계의 한 쪽 면에만 처리되어야 한다.
그리고 그 테이블은 데이터베이스 상에서 외래키를 가진다.
저장예시)
const profile = new Profile()
profile.gender = "male"
profile.photo = "me.jpg"
await dataSource.manager.save(profile)
const user = new User()
user.name = "Joe Smith"
user.profile = profile
await dataSource.manager.save(user)
캐스케이드 옵션을 사용하는 경우, 한번에 처리할 수 있다.
User를 Profile과 함께 불러오기 위해서는 FindOptions의 relation을 사용하거나 QueryBuilder를 써야 한다.
const users = await dataSource.getRepository(User).find({
relations: {
profile: true,
},
})
const users = await dataSource
.getRepository(User)
.createQueryBuilder("user")
.leftJoinAndSelect("user.profile", "profile")
.getMany()
eager 옵션을 사용하는 경우, 굳이 relation을 사용하지 않아도 알아서 로드를 해준다. 하지만 QueryBuilder 사용시에는 eager 옵션이 처리되지 않아 leftJoinAndSelect를 처리해야 한다.
위 예시를 양방향으로 바꾸면 이렇다.
import { Entity, PrimaryGeneratedColumn, Column, OneToOne } from "typeorm"
import { User } from "./User"
@Entity()
export class Profile {
@PrimaryGeneratedColumn()
id: number
@Column()
gender: string
@Column()
photo: string
@OneToOne(() => User, (user) => user.profile) // specify inverse side as a second parameter
user: User
}
import {
Entity,
PrimaryGeneratedColumn,
Column,
OneToOne,
JoinColumn,
} from "typeorm"
import { Profile } from "./Profile"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@OneToOne(() => Profile, (profile) => profile.user) // specify inverse side as a second parameter
@JoinColumn()
profile: Profile
}
@JoinColumn이 한쪽에 매핑된 것에 주의해라. 외래키를 가지는 쪽.
양방향 매핑은 다른 방향에서 QueryBuilder를 통한 데이터를 가져오는 것을 허용한다.
const profiles = await dataSource
.getRepository(Profile)
.createQueryBuilder("profile")
.leftJoinAndSelect("profile.user", "user")
.getMany()
'프로그래밍 > TypeORM' 카테고리의 다른 글
[TypeORM] Relations (0) | 2023.09.04 |
---|---|
[TypeORM] Many-to-one / one-to-many relations (0) | 2023.09.04 |
[TypeORM] Find Options - Advanced options (0) | 2023.09.02 |
[TypeORM] Find Options - Basic Options (0) | 2023.09.02 |
[TypeORM] EntityManager API (0) | 2023.09.02 |
댓글