JPA 연관관계 매핑 - 조인 테이블(@JoinTable)


조인 테이블

데이터베이스 테이블의 연관관계를 설계 하는 방법은 크게 두가지 입니다.
첫 번째는 앞서 복합키 매핑에서 살펴 보았듯이 외래키를 가지고 연관관계를 설계 하는 조인 컬럼 방법과 테이블과 테이블 사이에 별도의 조인 테이블을 만들어 양 테이블간의 연관관계를 설정 하는 방법이 있습니다. 이번 시간에는 조인테이블을 만들어서 테이블간의 연관 관계를 설정하는 방법에 대해서 정리 해보겠습니다.

조인 테이블

조인테이블 관계
조인 테이블 관계

조인테이블은 외래키를 사용 하는 연관 관계와는 다르게 조인테이블(Member_Teacher)이라는 별도의 테이블을 만들어서 각 테이블의 외래키를 가지고 연관관계를 관리 합니다. 이 방법의 가장큰 단점은 테이블이 하나 생성 되기 때문에 관리해야 할 테이블이 늘어나고 데이터를 조회 할때 조인테이블을 조인해야 하는 단점이 있습니다.
하지만 조인테이블을 이용해야 하는 설계 부분이 있기 때문에 여러가지 유형의 조인테이블을 사용 하는 방법을 알아 보겠습니다.

@JoinTable 속성

옵션 설명
name 조인 테이블 명
joinColumns 현재 엔티티를 참조하는 외래키
inverseJoinColumns 반대방향 엔티티를 참조하는 외래키

1:1 조인 테이블

일대일 조인테이블 관계

  • 엔티티 클래스

      @Entity
      public class Member {
          @Id
          @Column(name = "MEMBER_ID")
          private String id;
            
          @Column(name = "MEMBER_NAME")
          private String name;
            
          @OneToOne
          @JoinTable(name = "MEMBER_TEACHER", //조인테이블명
                     joinColumns = @JoinColumn(name="MEMBER_ID"),  //외래키
                     inverseJoinColumns = @JoinColumn(name="TEACHER_ID") //반대 엔티티의 외래키
                     )
          private Teacher teacher;
          //...getter, setter
      }
        
      @Entity
      public class Teacher {
          @Id
          @Column(name = "TEACHER_ID")
          private String id;
            
          @Column(name = "TEACHER_NAME")
          private String name;
          //...getter, setter
      }
    
  • 테스트 클래스

       Teacher teacher = new Teacher("KIM", "김일타");
       em.persist(teacher);
         
       Member member = new Member("NO1", "홍길동");
       member.setTeacher(teacher);
       em.persist(member);
    
  • 테스트 결과

    일대일 조인테이블 결과

1:N 조인테이블

일대다 조인테이블 관계

  • 엔티티 클래스

      @Entity
      public class Member {
        	
      	@Id
      	@Column(name = "MEMBER_ID")
      	private String id;
        	
      	@Column(name = "MEMBER_NAME")
      	private String name;
        	
      	@OneToMany
      	@JoinTable(name = "MEMBER_TEACHER", //조인테이블명
                             joinColumns = @JoinColumn(name="MEMBER_ID"),  //외래키
                             inverseJoinColumns = @JoinColumn(name="TEACHER_ID") //반대 엔티티의 외래키
                             )
      	private List<Teacher> teacher= new ArrayList<Teacher>();
          //.. getter, setter
      }
        
      @Entity
      public class Teacher {
          @Id
          @Column(name = "TEACHER_ID")
          private String id;
            
          @Column(name = "TEACHER_NAME")
          private String name;
          //...getter, setter
      }
    
  • 테스트 클래스

      Teacher teacher = new Teacher("KIM", "김일타");
      em.persist(teacher);
    
      Teacher teacher2 = new Teacher("PARK", "박이타");
      em.persist(teacher2);
         
      Member member = new Member("NO1", "홍길동");
      member.addTeacher(teacher);
      member.addTeacher(teacher2);
      em.persist(member);
    
  • 테스트 결과

    일대다 조인테이블 결과

N:1 조인테이블

일대다 조인테이블 관계

  • 엔티티 클래스

      @Entity
      public class Member {
      	@Id
      	@Column(name = "MEMBER_ID")
      	private String id;
        	
      	@Column(name = "MEMBER_NAME")
      	private String name;
        	
      	@ManyToOne
      	private Teacher teacher;
          //.. getter, setter
      }
        
      @Entity
      public class Teacher {
      	@Id
      	@Column(name = "TEACHER_ID")
      	private String id;
        	
      	@Column(name = "TEACHER_NAME")
      	private String name;
        
      	@OneToMany
      	@JoinTable(name = "MEMBER_TEACHER",
      				joinColumns = @JoinColumn(name = "TEACHER_ID"),
      				inverseJoinColumns = @JoinColumn(name = "MEMBER_ID"))
      	private List<Member> member = new ArrayList<Member>();
          //...getter, setter
      }
    
  • 테스트 클래스

       Teacher teacher = new Teacher("KIM", "김일타");
            	         
       Member member = new Member("NO1", "홍길동");
       member.setTeacher(teacher);
       em.persist(member);
        
       Member member2 = new Member("NO2", "이순신");
       member2.setTeacher(teacher);
       em.persist(member2);
         
       teacher.addMember(member);
       teacher.addMember(member2);
       em.persist(teacher);
    
  • 테스트 결과

    다대일 조인테이블 결과

N:M 조인 테이블

다대다 조인테이블 관계

  • 엔티티 클래스

      @Entity
      public class Member {
      	@Id
      	@Column(name = "MEMBER_ID")
      	private String id;
        	
      	@Column(name = "MEMBER_NAME")
      	private String name;
        	
      	@ManyToMany
      	@JoinTable(name = "MEMBER_TEACHER", 
      	   joinColumns = @JoinColumn(name="MEMBER_ID"),
      	   inverseJoinColumns = @JoinColumn(name="TEACHER_ID")
      	   )
      	private List<Teacher> teacher = new ArrayList<Teacher>();
          //.. getter, setter
      }
        
      @Entity
      public class Teacher {
      	@Id
      	@Column(name = "TEACHER_ID")
      	private String id;
        	
      	@Column(name = "TEACHER_NAME")
      	private String name;
          //...getter, setter
      }
    
  • 테스트 클래스

       Teacher teacher = new Teacher("KIM", "김일타");
       em.persist(teacher);
       Teacher teacher2 = new Teacher("PARK", "박이타");
       em.persist(teacher2);
         
       Member member = new Member("NO1", "홍길동");
       Member member2 = new Member("NO2", "이순신");
         
       member.addTeacher(teacher);
       em.persist(member);
         
       member2.addTeacher(teacher);
       member2.addTeacher(teacher2);
       em.persist(member2);
    
  • 테스트 결과

    다대다 조인테이블 결과

마무리

조인테이블을 이용한 연관관계에 대해서 다루어 보았습니다. 조인 테이블을 이용한 연관관계 매핑 과 이전에 다루었던 복합키 매핑을 사용 하여 실무에 필요한 매핑을 할 수 있을 것입니다.

Back to blog