ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JPA] 다양한 연관 관계 매핑 ( N:1 / 1:N / 1:1 / N:M )
    DEV/JPA 2024. 4. 4. 03:43

    * 정보전달의 목적이 아닌 개인 스터디 정리 글 입니다.

     

    강의 : 인프런 <자바 ORM 표준 JPA 프로그래밍 기본편>

    교육자 : 김영한


    연관관계 매핑시 고려사항

    • 다중성
      • 다대일 : @ManyToOne
      • 일대다 : @OneToMany
      • 일대일 : @OneToOne
      • 다대다 : @ManyYoMany
    • 단방향, 양방향
      • 테이블 : 외래키로 양쪽 조인 가능, 방향개념 없음
      • 객체 : 참조용 필드가 있는 쪽으로만 참조 가능, 한쪽만 참조하면 단방향, 양쪽 서로 참조하면 양방향
    • 연관관계의 주인
      • 외래키를 관리하는 참조가 주인
      • 주인의 반대편은 외래키에 영향을 주지않고 단순 조회만 가능

     

    1. 다대일 (N:1)
    : 외래키있는곳에 객체 참조 걸어주기

     

    1-1. 다대일 단방향

    - 가장 많이 사용하는 연관관계

    - 다대일의 반대는 일대다

    1-2. 다대일 양방향

    - 외래키가 있는 쪽이 연관관계의 주인

    - 양쪽을 서로 참조하도록 개발
    - 반대쪽은 객체 추가만함. 읽기만 가능. 테이블 영향없음

     

    2. 일대다 (1:N)

    2-1. 일대다 단방향
    1이 연관관계의 주인

    - N쪽에 외래키가 있음

    - 객체와 테이블의 차이 때문에 반대편 테이블의 외래키를 관리하는 구조

     

    * 유의사항

    - team을 insert 했는데 member의 update쿼리가 추가됨

    Member 테이블이 Update 쿼리가 나가는 모습


    - Joincolumn 어노테이션을 넣지않으면 하이버네이트가 중간테이블을 하나 추가함

    Member와 Team의 중간테이블 Team_Member가 생성되는 모습

     

    일대다 단방향 매핑의 단점

    - 엔티티가 관리하는 외래키가 다른(상대) 테이블에 있음

    - 연관관계 관리를 위해 추가로 UPDATE SQL이 실행됨

    => 일대다 단방향 매핑보다 다대일 양방향 매핑을 사용을 권장



    2-2. 일대다 양방향
    : 공식적으로는 존재하지않고 야매로 속성을 넣어서 읽기전용으로 만들어야함

    - @JoinColumn(insertable=false, updateable=false) 이와 같이 읽기 전용 필드를 사용해서 양방향 처럼 사용

    => 다대일 양방향 사용을 권장

     

    3. 일대일 (1:1)
    : 일대일 관계는 그 반대도 일대일

    - 주 테이블이나 대상 테이블 중 외래키 선택 가능

    - 외래키에 데이터베이스 유니크 제약조건 추가

     

    3-1. 주 테이블에 외래키 단방향

    - 다대일 단방향 매핑과 유사

     

    3-2. 주 테이블에 외래키 양방향

    - 다대일 양방향 매핑 처럼 외래키가 있는 곳이 연관관계의 주인

    - 반대편은 mappedBy 적용

     

    3-3. 대상 테이블에 외래키 단방향

    - 단방향 관계는 JPA 지원하지 않음

    - 양방향 관계는 지원

     

    3-4. 대상 테이블에 외래키 양방향

    - 일대일 주 테이블에 외래키 양방향과 매핑 방법이 같음 (테이블 반대로 뒤집는 차이)

     

    * 장단점 정리

    - 주 테이블에 외래키 : 객체지향 개발자 선호, JPA 매핑 편리

    • 장점 : 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인가능
    • 단점 : 값이 없으면 외래키에 null허용

     

    - 대상 테이블에 외래키 : 데이터베이스 개발자 선호 (테이블 변경할 변수가 적음)

    • 장점 : 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지가능
    • 단점 : 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨



    4. 다대다(N:M)
    : 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없음

    - 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어야함

    - 객체는 컬렉션을 사용해서 객체 2개로 다대다 관계 가능

    - @ManyToMany 사용, @JoinTable로 연결 테이블 지정

    - 다대다 매핑 : 단방향, 양방향 가능


    다대다 => 실무에서 쓰면 안된다 ?

    이유
    : 연결테이블이 필요한데 실무에서는 단순하게 연결만 하고 끝나지않음. ( 테이블에 계속 필요한 데이터가 추가될 수 있음 )
    따라서 일대다, 다대일로 풀어서 사용할것. 중간테이블을 엔티티로 승격!

    ex) Member와 Product 사이의 중간테이블 (Memeber_Product)을 Order 테이블로 바꾸어 엔티티로 만들기

     

    * 주요 어노테이션 속성 설명

    @JoinColumn : 외래키 매핑시 사용

    속성 설명 기본값
    name 매핑할 외래 키 이름 필드명 + _ + 참조하는 테 이블의 기본 키 컬럼명
    referencedColumnName 외래 키가 참조하는 대상 테이블의 컬럼명 참조하는 테이블의 기본 키 컬럼명
    foreignKey(DDL) 외래 키 제약조건을 직접 지정할 수 있다. 이 속성은 테이블을 생성할 때만 사용한다.  
    unique
    nullable
    insertable
    updatable
    columnDefinition
    table
    @Column의 속성과 같다.  

     

    @ManyToOne :  다대일 관계 매핑

    속성 설명 기본값
    optional false로 설정하면 연관된 엔티티가 항상 있어야 한다. TRUE
    fetch 글로벌 페치 전략을 설정한다. - @ManyToOne=FetchType.EAGER
    - @OneToMany=FetchType.LAZY
    cascade 영속성 전이 기능을 사용한다.  
    targetEntity 연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거 의 사용하지 않는다. 컬렉션을 사용해도 제네릭으로 타 입 정보를 알 수 있다.  

     

    @OneToMany : 일대다 관계 매핑

    속성 설명 기본값
    mappedBy 연관관계의 주인 필드를 선택한다.  
    fetch 글로벌 페치 전략을 설정한다. - @ManyToOne=FetchType.EAGER
    - @OneToMany=FetchType.LAZY
    cascade 영속성 전이 기능을 사용한다.  
    targetEntity 연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거 의 사용하지 않는다. 컬렉션을 사용해도 제네릭으로 타 입 정보를 알 수 있다.  

    댓글

Designed by Tistory.