공통

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

단방향 연관관계

  • 쉽게 예제로 설명

  • 회원과 팀이 있고, 회원은 하나의 팀에만 소속될 수 있다. (회원과 팀은 다대일 관계)


  • 연관관계가 없는 객체

    • MEMBER 테이블에서 TEAM의 PK를 외래키로 갖고 있고,
    • Member 객체에서 Team의 객체를 저장하고 생긴 PK를 저장하는 teamId 컬럼을 갖고 있다.
      (즉, 참조 대신 외래 키를 그대로 사용해서 식별자를 직접 다룸 = 객체지향적 방법 X)
    • 그래서 Member조회 > teamId 조회 > Team 데이터 얻는 과정이 된다.

  • 추구 방향

    • 객체를 테이블에 맞춰 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다.
    • 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다.
    • 객체는 참조를 사용해서 연관된 객체를 찾는다.
    • 테이블과 객체 사이에는 이런 큰 간격이 있다.


  • 연관관계가 있는 객체

    • 테이블의 변화는 없고, 사용하는 객체에서 외래키가 아닌 Team 객체를 선언해서 사용

    • 그럼 Member 조회 > team 조회가 바로 가능하다.

    • 저장 시

       // 팀 저장 
       Team team = new Team();
       team.setName("TeamA");
       em.persist(team);
      
       // 회원 저장
       Member member = new Member();
       member.setName("member1");
       member.setTeam(team); // 단방향 연관관계 설명, 참조 저장
       em.persist(member);

    • 참조로 연관관계 조회 - 객체 그래프 탐색

      //조회
       Member findMember = em.find(Member.class, member.getId());
       
       //참조를 사용해서 연관관계 조회
       Team findTeam = findMember.getTeam();

    • 수정 시

      // 새로운 팀B 
      Team teamB = new Team();
      teamB.setName("TeamB");
      em.persist(teamB);
      
      //회원1에 새로운 팀B 설정
      member.setTeam(teamB);

양방향 연관관계

  • 객체와 테이블간에 연관관계를 맺는 차이를 이해해야한다.
- 객체 연관관계 = 2개
 - 회원 > 팀 연관관계 1개 (단방향)
 - 팀 > 회원 연관관계 1개 (단방향)

 
- 테이블 연관관계 = 1개
  - 회원 <> 팀의 연관관계 1개(양방향)
  • 여기서 이해해야할 포인트는 단방향, 양방향 관계는 사실상 구분하기 위한 것이고 회원(팀)을 알기 위해서는 팀(회원)의 정보가 필요하니까 단방향이고,
    테이블에서의 연관관계는 FK 하나면 양쪽에서의 조회가 가능하니까 양방향이라고 생각하면 된다.

  • 정리 (중요한 의미라 한번 더 설명)

    • 객체의 양방향 연관관계 (객체!!)

      • 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개이다.
      • 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
      • EX. A->B(a.getB()
    • 테이블의 양방향 연관관계

      • 테이블은 외래 키 하나로 두 테이블의 연관관계를 관리
      • MEMBER.TEAM_ID 외래 키 하나로 양방향 연관관계 가짐(양쪽으로 조인할 수 있다.)
    • SELECTR * FROM MEMBER M JOIN TEAM T ON M.TEAM_ID = T.TEAM_ID

    • SELECT * FROM TEAM T JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID

  • 그래서 둘 다 외래키를 갖고 있으니까 둘 중 하나로 외래 키를 관리해야 한다.

  • 연관관계 주인 ( Owner )

    • 양방향 매핑 규칙
      • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정
      • 연관관계 주인만이 외래 키를 관리(등록, 수정)
      • 주인이 아닌 쪽은 읽기만 가능
      • 주인은 mappedBy 속성 사용 x
      • 주인이 아니면 mappedBy 속성으로 주인 지정

    • 즉, 주인은 외래 키가 있는 곳을 주인으로 정해야 한다.
      그리고 주인은 mappedBy로 지정하면 데이터 조회 외에는 어떠한 동작도 하지 않는다.
profile
까먹지말자

0개의 댓글