ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 연관관계 매핑 기초 - 양방향 연관관계
    김영한(인프런 강의)/자바 ORM 표준 JPA 프로그래밍 2020. 10. 7. 15:30
    반응형

    객체와 테이블이 관계를 맺는 관계

    연관관계

    1. 양방향 객체 연관관계

        1) 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단 뱡향 관계 2개다.

        2) 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어 야 한다. 

            - A -> B (a.getB())

            - B -> A (b.getA())

    class A {
     B b;
    }
    
    class B {
     A a;
    }

     

    2. 테이블 연관관계

         1) 테이블은 외래 키 하나로 두 테이블의 연관관계를 관리

         2) MEMBER.TEAM_ID 외래 키 하나로 양방향 연관관계 가짐 (양쪽으로 조인할 수 있다.)

           - 아래와 테이블 관계처럼 둘중 하나로 왜래 키를 관리해야 한다.

    SELECT * 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)

    1. 양방향 매핑 규칙

        1) 객체의 두 관계중 하나를 연관관계의 주인으로 지정

        2) 연관관계의 주인만이 외래 키를 관리(등록, 수정)

        3) 주인이 아닌쪽은 읽기만 가능

            - Team에 존재하는 List Members는 읽기만 가능

        4) 주인은 mappedBy 속성 사용X

        5) 주인이 아니면 mappedBy 속성으로 주인 지정

    연관 관계

     

    위의 테이블 관계를 보게 된다면 Team이 Member보다 상위에 존재한다.(Member는 Team에 속하기 때문에) 하지만 객체 관계에서는 거꾸로 생각해야 된다. 그 이유는 Team기준으로 객체를 설계하게되면 List의 멤버를 관리하기가 힘들뿐더러 성능이 좋지 않기 때문이다.

     

    2. 양방향 매핑시 주로 하는 실수

        1) 연관관계의 주인을 입력 하지 않을 경우

            - MEMBER의 TEAM_ID가 NULL로 저장

            - 양방향 매핑 시 연관관계의 주인에 값을 입력해야함 ( member.setTeam(team); )

                - 순수한 객체 관계를 고려하면 항상 양쪽다 값을 입력 해야함

    Team team = new Team();
     team.setName("TeamA");
     em.persist(team);
     
     Member member = new Member();
     member.setName("member1");
     
     //member.setTeam(team); (연관관계 설정 해야 함)
     //역방향(주인이 아닌 방향)만 연관관계 설정
     team.getMembers().add(member);
     em.persist(member);

    테이블에 저장된 결과

     

    3. 양방향 매핑 정리

        1) 단방향 매핑만으로도 이미 연관관계 매핑은 완료

        2) 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐

        3) JPQL에서 역방향으로 탐색할 일이 많음

        4) 단방향 매핑을 잘 하고 양방향은 필요할 때 추가해도 됨 (테이블에 영향을 주지 않음

     

     

    공통코드

    @Entity
    public class Team {
    	@Id
    	@GeneratedValue
    	@Column(name = "TEAM_ID")
    	private Long id;
    	private String name;
    
    	@OneToMany(mappedBy = "team")
    	private List<Member> members = new ArrayList<Member>();
        
        Getter(), Settter() ...
    }

     

    @Entity
    public class Member {
    	@Id
    	@GeneratedValue
    	private Long id;
    	@Column(name = "USERNAME")
    	private String name;
    	private int age;
    	@ManyToOne
    	@JoinColumn(name = "TEAM_ID")
    	private Team team;
        
        Getter(), Setter() ...
    }

     

    반응형
Designed by Tistory.