단방향 연관관계를 이해하고 기본적인 객체지향 모델링 방법을 익힌다.

인프런 강의 참고

단방향 연관관계

Goal

  • 객체와 테이블 연관관계의 차이를 이해한다.
  • 객체의 참조와 테이블의 외래 키를 어떻게 매핑하는지 안다.
  • 용어 이해
    • 방향 (Direction)
      • 단방향, 양방향
    • 다중성 (Multiplicity)
      • 다대일 (N:1), 일대다 (1:N), 일대일 (1:1), 다대다 (N:N)
    • 연관관계의 주인 (Owner)
      • 객체 양방향 연관관계는 관리하는 주인이 필요하다.

연관관계가 필요한 이유

예제 시나리오

1. 객체를 테이블에 맞추어 모델링 (연관 관계가 없는 객체)

그림 추가

@Entity
public class Member {
  @Id
  @GeneratedValue
  private Long id;
  
  @Column(name = "USERNAME")
  private String username;
  
  private int age;
  
  @Column(name = "TEAM_ID")
  private Long teamId;
  ...
}
@Entity
public class Team {
  @Id
  @GeneratedValue
  private Long id;
  
  private String name;
  ...
}

Q. 객체를 테이블에 맞추어 모델링 했을 때의 문제점?

단방향 연관관계 매핑 이론

2. 객체 지향 모델링 (객체 연관관계 사용)

그림 추가

@Entity
public class Member {
  @Id
  @GeneratedValue
  @Column(name = "MEMBER_ID")
  private Long id;
  
  @Column(name = "USERNAME")
  private String username;
  
  private int age;
  
//  @Column(name = "TEAM_ID")
//  private Long teamId;
  
  @ManyToOne
  @JoinColumn(name = "TEAM_ID") // 매핑 
  private Team team;
  ...
}
  1. 외래 키 대신에 Team 객체를 넣고 TEAM_ID를 매핑한다.
  2. 조인할 컬럼을 명시한다.
    • @JoinColumn으로 조인 컬럼을 명시한다.
    • 안적어도 default로 들어가지만, 적어 주는 것이 좋다.
  3. 연관관계를 맺는다.
    • Member —N:1— Team
    • Member 입장에서는 다대일, Team 입장에서는 일대다의 관계를 갖는다.
    • @ManyToOne으로 연관관계를 설정한다.
    • Team 이라는 필드가 DB의 “TEAM_ID”라는 외래 키와 매핑된다.

ORM 매핑

그림 추가

FetchType 옵션

[참고] 영속성 1차 캐시에서 가져오지 않고 DB Query를 날려서 직접 확인하고 싶으면,

entityManager(member);

// 추가
entityManager.flush(); // 현재 영속성 컨텍스트에 있는 것을 DB에 던져서 sync를 맞춘다.
entityManager.clear(); // 영속성 컨텍스트를 초기화시킨다.

Member findMember = entityManager.find(Member.class, member.getId()); // find 시 날라가는 쿼리를 확인한다.

연관관계 수정

// 새로운 팀B
Team teamB = new Team();
teamB.setName("TeamB");
entityManager.persist(teamB);

// 회원1에 새로운 팀B 설정
member.setTeam(teamB);

관련된 Post

Reference