6. 다양한 연관관계 매핑 (일대일)

HotFried·2023년 9월 26일
0

일대일 관계

  • 일대일 관계는 그 반대도 일대일

  • 주 테이블이나 대상 테이블 중에 외래 키 선택 가능

    • 주 테이블에 외래 키
    • 대상 테이블에 외래 키

  • 외래 키에 데이터베이스 유니크 제약조건 추가


주 테이블에 외래 키 단방향

Member 엔티티

@Entity
public class Member {

    @Id
    @GeneratedValue
    private Long id;
    private String username;

    @OneToOne
    @JoinColumn(name = "LOCKER_ID")
    private Locker locker;
}

Locker 엔티티

@Entity
public class Locker {

    @Id @GeneratedValue
    @Column(name = "LOCKER_ID")
    private Long id;
    private String name;
}
  • 다대일@ManyToOne 단방향 매핑과 유사하다.

주 테이블에 외래 키 양방향

주 테이블에 외래 키 단방향 Locker엔티티 코드에 아래의 코드만 추가하면 된다.

    @OneToOne(mappedBy = "locker")
    private Member member;
  • 외래키가 있는 곳이 연관관계의 주인이 되고 반대편은 mappedBy적용

대상 테이블에 외래 키 단방향

  • Member가 연관 관계의 주인이 되고 싶은데 테이블에서 외래키가 Locker에 있는 상태

  • 단방향 관계는 JPA가 지원하지 않는다.


대상 테이블에 외래 키 양방향

1:1은 외래키를 어디에 둬도 상관이 없다면, member에 있는게 좋을까 locker에 있는게 좋을까?

-> 미래에 회원 한 명이 여러 라커를 가질 수 있도록 바뀐다면, locker에 외래키를 두는 양방향이 좋을 것이다.
(locker에 있는 member_id의 유니크 제약 조건만 alter로 제거하면 되기 때문이다.)


  • 솔루션 마다 방향이 반대가 될 수 있다.
  • 보통 member에 locker_id가 있는 게 더 유리하다.

비즈니스에서는 회원 조회가 많이 일어나기 때문에, 라커 정보를 가져올 때도 조인할 필요 없이 쿼리 한 방으로 라커 정보를 알 수 있는 성능 상의 이점이 있다.
(회원이 어떤 라커를 이용하고 있는지 조회하는 경우가 많다.)


정리

  • 주 테이블에 외래 키

    • 주 객체가 대상 객체의 참조를 가지는 것 처럼
      주 테이블에 외래 키를 두고 대상 테이블을 찾는다.
    • 객체지향 개발자 선호
    • JPA 매핑이 편리하다.
    • 장점 : 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인 가능
    • 단점 : 값이 없으면 외래 키에 null 허용
  • 대상 테이블에 외래 키

    • 대상 테이블에 외래 키가 존재
    • 전통적인 데이터베이스 개발자가 선호
    • 장점 : 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지
    • 단점 : 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨
      • Member.locker를 조회할 때, JPA는 프록시를 만들기 위해 Member.locker에 값이 있는지 미리 알아야 한다.
      • 값을 알려면 member만 조회하는 게 아니라 locker 테이블도 함께 조회해야 한다.
        (Member에 외래키가 존재하지 않기 때문이다.)
      • 쿼리가 나갔으니 프록시로 만들 이유가 없기 때문에 즉시 로딩된다.

참고 :

김영한. 『자바 ORM 표준 JPA 프로그래밍』. 에이콘, 2015.

자바 ORM 표준 JPA 프로그래밍 - 기본편

profile
꾸준하게

0개의 댓글