4. 연관관계 매핑

신명철·2022년 2월 11일
0

JPA

목록 보기
4/14
post-custom-banner

연관관계의 필요성

객체지향 설계의 목표는 객체들간의 협력 공동체를 만드는 것이다.

@JoinColumn

외래키를 참조할 때 사용한다. 즉, 외래키에 달아준다.

  • 속성
    • name
    • referencedColumnName
    • foreignKey
    • unique/nullable/insertable/updatable/columnDefinition/table

@ManyToOne

다대일 관계 매핑

  • 속성
    • optional
    • fetch
    • cascade
    • targetEntity

@OneToMany

다대일 관계 매핑

  • 속성
    • mappedBy
    • fetch
    • cascade
    • targetEntity

단방향 연관관계

  • FK 로 연관된 테이블의 PK 를 참조시킨다.
  • FK 에 @JoinColumn(name = "...") 로 설정할 수 있다.

양방향 연관관계

  • 테이블 관점에서의 양방향 연관관계
    • 하나의 외래 키두 테이블의 연관관계를 관리하는 것
    • 사실 방향이라는 개념이 없음
    • e.g) A<->B
  • 객체 관점에서의 양방향 연관관계
    • 서로 다른 단방향 관계 2 개
    • 참조용 필드가 있는 쪽으로만 참조 가능
    • e.g) A->B, B->A

연관관계의 주인

양방향 매핑의 두 객체중 하나를 연관관계의 주인으로 지정해야 한다. 연관관계의 주인만이 외래 키를 관리하고, 주인이 아닌쪽은 읽기만 가능하다.

  • 주인이 아닌 곳에서 mappedBy 속성으로 주인을 지정해줘야 한다.
    • mappedBy 는 읽기 전용으로, 값을 넣어도 DB 에 적용되지 않는다.
  • 연관관계의 주인은 외래 키가 있는 쪽을 기준으로 정해야 한다.
    • 보통 多 쪽이 주인이 된다.
  • 연관관계의 주인 : 외래 키를 관리하는 참조
  • 주인의 반대편: 외래 키에 영향을 주지 않고 단순 조회만 가능하다.

주의 : 연관관계의 주인에 값을 꼭 입력해야 한다. (순수한 객체 관계를 고려해 양쪽에 값을 넣어주자)

참고 : N대M 의 N쪽이 연관관계의 주인이다. (의도적으로 배치했음)

다대일 [N:1]

다대일 단방향

  • 가장 많이 사용하는 연관관계로 多 쪽에 외래 키가 있고, 연관관계의 주인이 된다.

다대일 양방향

  • 양쪽을 서로 참조하도록 개발하자.
  • 외래키가 있는 쪽이 연관관계의 주인이 된다.

일대다 [1:N]

일대다 단방향

  • 1:N 에서 1이 연관관계의 주인이다.
  • 항상 N 쪽에 외래 키가 있다.
    • 여기서 의문점이 있을 것이다. 보통 多 쪽이 연관관계의 주인이 된다고 했기 때문이다.
    • 객체 기준에서는 Member(N)은 Team(1)을 모르고 있다. 그러나 Team(1)은 자신에게 속한 모든 Member(N)들을 알고 있다. Member(N)에게 외래 키가 없기 때문에 어쩔 수 없이 Team(1)에 외래키가 존재하는 상황이 발생한 것이다.
  • 객체와 테이블의 차이 때문에 반대편 테이블의 외래키를 관리하는 특이한 구조
  • @JoinColumn 을 꼭 사용해줘야 한다. 그렇지 않으면 조인 테이블 방식을 사용하게 됨

=> 일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용하자

일대일[1:1]

일대일 단방향 매핑

  • 주 테이블이나 대상 테이블 중 외래 키를 선택할 수 있다. 즉, 양쪽 어디든 들어갈 수 있음
  • 외래 키에 DB 유니크(UNI) 제약조건 추가
  • 반대편에 mappedBy 를 추가하면 양방향으로 만들 수 있다.
  • 단방향 관계는 JPA 에서 지원하지 않는다
  • 양방향 관계는 지원함

다대다[N:M]

  • 관계형 DB 는 정규화된 테이블 2개로 다대다 관계를 표현할수 없다.
    • 연결 테이블을 추가해 일대다 + 다대일 관계로 풀어내야만 한다.
  • 다만 객체는 객체 2개로 다대다 관계가 가능하다!
  • 편리해보이지만 실무에선 사용하지 않는다.
    • 연결 테이블은 매핑만 하고 끝나지 못한다. 실무에서는 요구 데이터가 필요한 경우가 분명 생기기 때문이다.
    • 예를 들어서, 주문 시간이나 수량 같은 데이터가 들어갈 수 있다.
  • @ManyToMany 에는 필드가 추가할 수 없고 엔티티 테이블이 불일치하기 때문에 사용하지 말아야 한다.

다대다의 한계 극복

  • 연결 테이블용 엔티티를 추가한다.
    • 연결 테이블을 엔티티로 승격시킨다.
  • @ManyToMany -> @OneToMany, @ManyToOne

출처

profile
내 머릿속 지우개
post-custom-banner

0개의 댓글