[JPA] 연관관계 매핑 기초

Jiisuniui·2023년 12월 12일
0

JPA의 모든 것

목록 보기
4/8
post-thumbnail

연관관계 매핑 기초

1. 목표

  • 객체와 테이블 연관관계의 차이 이해
  • 객체의 참조와 테으블의 외래 키를 매핑
  • 연관관계 용어
    • 방향(Direction): 단방향, 양방향
    • 다중성(Multiplicity): 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M) 이해
    • 연관관계의 주인(Owner): 객체의 양방향 연관관계는 관리 필요

2. 연관관계가 필요한 이유

  • 객체지향 설꼐의 목표는 자율적인 객체들의 협력 공동체를 만드는 것이다
    • 책추천!
    • 객체지향의 사실과 오해: 조영호
    • 오브젝트: 조영호

3. 단방향 연관관계

  • @ManyToOne @OneToOne
  • @JoinColumn(name="TEAM_ID")
    @Entity
    public class Member{
      @ManyToOne
      @JoinColumn(name="TEAM_ID")
      private Team team;
    }

4. 양방향 연관관계와 연관관계의 주인

기본적으로 알아야될 것

  • 객체는 참조를하고, join은 외래키로 하는데 이거에 대한 차이를 알아야됨
  • 테이블 : 양방향, 단방향이라는 개념 자체가 없음 -> fk 사용해서 왔다갔다가 가능 -> 기본적으로 양방향
  • 객체 : 단방향은 단방향으로만 알수있음 (반대로는 못 봄)

사용 방법

  • @OneToMany(mappedBy = "team") -> team이 Member에서 참조한 이름!!!!
  • @OneToOne(mappedBy = "team")
    @Entity
    public class Team{
      @OneToMany(mappedBy="team")
      private List<Member> members = new ArrayList<>();
    }

mappedBy란?

  • 객체와 테이블이 관계를 맺는 차이
    • 객체 연관관계: 2개
      • 회원 -> 팀 연관관계(단방향)
      • 팀 -> 회원 연관관계(단방향)
    • 테이블 연관관계: 1개
      • 회원 <-> 팀 연관관계(양방향)
  • 객체의 양방향 관계
    • 객체의 양방향 관계는 사실 양방향이 아니라 서로 다른 단방향 관계 2개
    • 객체를 양방향으로 참조하려면 단방향 연관관계 2개를 만들어야됨
  • 테이블 양방향 관계
    • 테이블의 외래키를 사용해서 두 테이블의 연관관계를 관리
    • MEMBER.TEAM_ID 외래 키 하나로 양방향 연관관계 (양쪽으로 join 가능)
  • 객체 두개 중 하나로 외래 키를 관리해야됨

연관관계의 주인(Owner)

  • 양방향 매핑 규칙
    • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
    • 연관관계의 주인만이 외래 키를 관리(등록, 수정)
    • 주인이 아닌쪽은 읽기만 가능
    • 주인은 mappedBy 속성 사용x
    • 주인이 아니면 mappedBy 속성으로 주인 지정
  • 누구를 주인으로?
    • 외래키가 있는 곳을 주인으로 정하자
    • 위에서는 Member.team이 연관관계의 주인
    • 진짜매핑: 연관관계의 주인(Member.team)
    • 가짜매핑: 주인의 반대편(Team.members)

5. 주의점

  • 양방향 매핑시 가장 많이 하는 실수
    • 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자
    • 연관관계 편의 메소드를 생성하자
      • 코드에서 직접하는게 아니라 setTeam 자체에 설정
      • 하지만 setTeam은 기본 메소드기 때문에, changeTeam 이런식으로 하는게 좋음
      @Entity
      public class Member{
        public void changeTeam(Team team){
          this.team=team;
          team.getMembers().add(this)
        }
      }
    • 양방향 매핑시에 무한 루프를 조심하자
      • toString(): member.toString() -> team.toString() 호출 -> member.toString() 호출 반복
      • lombok
      • JSON 생성 라이브러리 : controller에서 entity 반환 절대 금지
        • 이부분은 논외로 entity가 변환되면 api가 강제로 바껴버림
        • 무조건 controller에서는 dto 반환되게

6. 정리

1. 양방향 매핑

  • 단방향 매핑만으로도 이미 연관관계 매핑은 완료
    • 설계는 무조건 단방향매핑!!!!!!
  • 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐
    • 설계상 필요할 때만! 양방향매핑
  • JPQL에서 역방향으로 탐색할 일이 많음
  • 단방향 매핑을 잘 하고 양방향은 필요할 때 추가해도 됨
    • 추가해도 테이블에 영향을 주지 않음

2. 연관관계의 주인을 정하는 기준 정리

  • 비즈니스 로직을 기준으로 연관관계의 주인을 선택하면 안됨
  • 연관관계의 주인은 외래키의 위치를 기준으로 정해야됨
profile
why error?

0개의 댓글