TypeORM을 사용한 엔티티 관계 정의(OneToOne)

hyejin·2024년 6월 28일
0

study-2024

목록 보기
9/17
post-custom-banner

1:1 관계

한 테이블의 각 행이 다른 테이블의 하나의 행과만 연관되는 관계를 의미한다. 이는 두 테이블 간의 일대일 대응 관계를 나타낸다. 대표적인 예로는 회원과 프로필 테이블이 있다.

OneToOne 관계 정의(단방향 관계 설정)

OneToOne 관계는 @JoinColumn() 으로 상대 엔티티의 기본 키를 외래 키로 지정하는데, 엔티티 중 반드시 한 쪽에만 설정해야 한다. 아래 예제에서는, 회원(User)이 프로필(Profile) 엔티티의 기본 키를 참조하는 외래 키를 가진다.

// import 생략

@Entity()
export class User {
  	@PrimaryGeneratedColumn()
  	id: number

  	@OneToOne(() => Profile, (profile) => profile.id, {
    	cascade: true,
    	eager: true,
      	onDelete: 'CASCADE',
      	onUpdate: 'CASCADE'
  	})
  	@JoinColumn()
    profile: Profile;
}

@Entity()
export class Profile {
  	@PrimaryGeneratedColumn()
  	id: number;

    @Column()
    firstName: string;

    @Column()
    lastName: string;

    @Column()
    age: number;
}
  • cascade:true
    • User 엔티티를 생성하며 동시에 Profile 엔티티 생성이 가능하다.
    • 이 옵션이 작성되어있지 않다면 User와 동시에 Profile 엔티티를 생성하려고 할 때 에러가 발생한다.
  • eager:true
    • User 엔티티를 조회할때 다른 설정을 하지않아도 Profile 정보가 함께 조회된다.
    • 이 옵션은 User 엔티티를 로드할 때 관련된 엔티티를 함께 로드하는 옵션이다.
  • onDelete:'CASCADE'
    • 외래키로 참조한 레코드가 삭제된 경우 해당 레코드로 함께 삭제된다.
    • Profile 엔티티가 삭제된 경우, User 엔티티에서 외래키로 참조하고 있는 레코드도 함께 삭제된다.
    • 해당 옵션을 지정하지 않은 경우, Profile 엔티티의 레코드를 삭제하려고 시도할때 에러가 발생한다.
  • onUpdate:'CASCADE'
    • 옵션은 외래키로 참조한 키 값이 업데이트 될 때, 외래 키도 함께 업데이트 된다.
    • Profile의 기본 키가 수정되면 User 엔티티의 외래 키도 동일하게 업데이트된다.
    • 해당 옵션을 지정하지 않은 경우, Profile 엔티티의 레코드를 수정하여도 외래키가 업데이트되지 않는다.

위와 같이 엔티티를 정의한다면, User 엔티티에서는 연결된 Profile 엔티티를 확인할 수 있지만, Profile 엔티티에서는 연결된 User 엔티티를 확인할 수 없다. Profile 엔티티에서도 User 엔티티를 확인하려면 양방향 관계를 설정해야 한다.

OneToOne 관계 정의(양방향 관계 설정)

// import 생략

@Entity()
export class User {
  	@PrimaryGeneratedColumn()
  	id: number

  	@OneToOne(() => Profile, (profile) => profile.user, {
    	cascade: true,
    	eager: true,
      	onDelete: 'CASCADE',
      	onUpdate: 'CASCADE'
  	})
  	@JoinColumn()
    profile: Profile;
}

@Entity()
export class Profile {
  	@PrimaryGeneratedColumn()
  	id: number;

    @Column()
    firstName: string;

    @Column()
    lastName: string;

    @Column()
    age: number;
  
  	@OneToOne(() => UserEntity, (user) => user.profile)
    user: UserEntity;
}

위와 같이 작성한다면, 이제 Profile 엔티티에서 relation을 사용하여 User 엔티티도 함께 조회가 가능하다.

const profile = await this.profileRepository.findOne({
    where: { id: 1 },
    relations: ['user'],
});

양방향 참조를 설정하면 다음과 같은 이점을 얻을 수 있다.

  • 데이터 접근이 용이해짐
  • 도메인 모델링이 직관적임
  • 데이터 무결성을 더 쉽게 유지할 수 있음
  • ORM 프레임워크의 다양한 기능과 성능 최적화 전략을 활용할 수 있음

[참고자료]

https://velog.io/@cabbage/TypeORM-One-to-one-%EA%B4%80%EA%B3%84OneToOne

profile
노는게 제일 좋아
post-custom-banner

0개의 댓글