ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JPA] 연관관계 매핑
    Back-end/JPA 2022. 4. 14. 09:59

    # 연관관계가 필요한 이유

    객체를 테이블에 맞춰 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다.

    - 테이블은 외래 키(FK)로 조인을 사용해 연관된 테이블을 찾는다.

    - 객체는 참조를 사용해 연관된 객체를 찾는다.

     

    # 연관관계 매핑시 고려사항 3가지

    • 단방향 vs. 양방향
    • 양방향 관계일 때의 연관관계의 주인
    • 다중성
      • @ManyToOne, @OneToMany, @OneToOne, @ManyToMany

     

    1. 단방향 vs. 양방향

    테이블

    • 외래 키 하나로 양쪽 조인 가능
    • 사실 방향이라는 개념이 없음

    객체

    • 참조용 필드가 있는 쪽으로만 참조 가능
    • 한쪽만 참조하면 단방향
    • 양쪽이 서로 참조하면 양방향

     

    # 단방향 연관관계

    객체 지향 모델링 - ORM 매핑

    객체 지향 모델링 - 객체의 참조와 테이블의 외래 키를 매핑

    @Entity
    public class Member {
    	
        @Id @GeneratedValue
        private Long id;
        
        @ManyToOne
        @JoinColumn(name = "team_id")
        private Team team;
        
        ...
    }

    객체 지향 모델링 - 연관관계 저장, 조회(객체 그래프 탐색), 수정

    //저장
    Team team = new Team();
    team.setName("TeamA");
    entityManager.persist(team);
    
    Member member = new Member();
    member.setName("member1");
    member.setTeam(team);	//단방향 연관관계 설정, 참조 저장
    entityManager.persist(member);
    
    //조회
    Member findMember = entityManager.find(Member.class, member.getId());
    
    Team findTeam = findMember.getTeam();	//참조를 사용해 연관관계 조회
    
    //수정
    Team teamB = new Team();
    entityManager.persist(teamB);
    
    member.setTeam(teamB);	//새로운 참조 설정

     

    # 양방향 연관관계

    양방향 매핑

    • DB 테이블에는 변화가 없고, 엔티티에서만 List 컬렉션이 추가된다.
    • 객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개이다.
      • 단방향 매핑만으로도 이미 연관관계 매핑은 완료된 것이다.
      • 양방향은 필요할 때 추가해도 된다. (어차피 테이블에 영향을 주지 않으니까)
      • 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐이다.
    • 테이블은 외래 키 하나로 양방향 연관관계(양쪽으로 조인 가능)를 가지고 두 테이블의 연관관계를 관리한다.

     

    2. 양방향 관계일 때의 연관관계의 주인

    • 양방향 관계 중 하나를 연관관계의 주인으로 지정해야 한다.
    • 연관관계의 주인만이 외래 키를 관리한다. (DB 테이블에 외래 키 등록 및 수정)
      • 연관관계의 주인 쪽에 값을 입력하지 않으면, DB 테이블의 FK 값이 null이 된다.
    • 주인이 아닌 쪽은 읽기만 가능하고, mappedBy 속성으로 주인을 지정해야 한다.
    • 외래 키가 있는 곳을 주인으로 정해라! (아래 예시에서는 Member.team이 연관관계의 주인이 됨)

     

    양방향 매핑 예시

    • Member.team이 연관관계의 주인일 때
      • Member 엔티티 코드는 위와 동일하고, Team 엔티티에만 컬렉션이 추가된다.
    @Entity
    public class Team {
    	
        @Id @GeneratedValue
        private Long id;
        
        @OneToMany(mappedBy = "team")
        List<Member> members = new ArrayList<>();
        
        ...
    }

     

    3. 다중성

    # 다대일(N:1) - 연관관계의 주인이 N인 쪽일 때

    다대일 단방향
    다대일 양방향

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

    → 양쪽을 서로 참조하도록 설정

     

     

    # 일대다(1:N) - 연관관계의 주인이 1인 쪽일 때

    일대다 단방향

    → 해당 경우는 일대다(1:N)에서 1이 연관관계의 주인인 경우이다.

    → DB 테이블의 일대다 관계에서는 항상 N 쪽에 외래 키가 존재한다. 

    → 권장하지 않고, 다대일 양방향 관계를 사용하자

    일대다 양방향

    → 위와 같은 매핑은 공식적으로 존재하지 않는다.

    → 읽기 전용 필드를 사용해 양방향처럼 사용하는 방법이다.

    → 권장하지 않고, 다대일 양방향 관계를 사용하자

     

    # 일대일(1:1)

    매핑방식1 - DB 주 테이블에 외래 키

    주 테이블에 외래 키 단방향

    → @ManyToOne 단방향 매핑과 유사

    주 테이블에 외래 키 양방향

    → 다대일 양방향 매핑처럼 테이블에 외래 키가 있는 곳이 연관관계의 주인이 된다.

    → 반대편은 mappedBy 속성으로 주인 설정

     

    매핑방식2 - DB 대상 테이블에 외래 키

    → 대상 테이블에 외래 키가 존재한다.

    → 장점: 주 테이블과 대상 테이블을 1:1에서 1:N 관계로 변경할 때 테이블 구조 유지 가능

    → 단점: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨 

     

    # 다대다(M:N)

    매핑방식1 - @ManyToMany로 처리

    → @JoinTable로 중개 테이블을 지정한다. 

    → 실무에서는 권장하지 않는다. (중개 테이블이 FK 이외의 필드를 가질 확률이 굉장히 높기 때문에)

     

    매핑방식2 - 연결 테이블용 엔티티 추가 (주로 이것 사용!)

    → @ManyToMany를 @OneToMany와 @ManyToOne으로 나누어 처리한다.

     

     

     

    'Back-end > JPA' 카테고리의 다른 글

    [JPA] 값 타입  (0) 2022.04.28
    [JPA] 프록시와 연관관계 관리  (0) 2022.04.28
    [JPA] 상속관계 매핑과 @MappedSuperclass  (0) 2022.04.27
    [JPA] 엔티티 매핑  (0) 2022.04.11
    [JPA] 등장 배경, 사용 이유, 간단 구동 방식  (0) 2022.03.31

    댓글

Designed by Tistory.