본문 바로가기
JPA

[JPA] 연관관계 매핑 - 단방향 연관관계

by snow_white 2022. 8. 7.

※ 인프런 강의 김영한님의 「자바 ORM 표준 JPA 프로그래밍」을 학습한 내용을 정리한 글입니다. 

 

  • 객체와 테이블 연관관계의 차이를 이해
  • 객체의 참조와 테이블의 외래 키를 매핑

 

  • 방향(Direction) : 엔티티의 관계가 어느쪽을 참조하고 있는지
    • 단방향 : 엔티티의 관계가 한 쪽만 참조하는 것
      ex) 회원 → 팀, 팀 → 회원
    • 양방향 : 엔티티의 관계가 양쪽 모두 참조하는 것
      ex) 회원 ↔ 팀
  • 다중성(Multiplicity) : 연관 관계가 있는 여러 개의 클래스가 있을 때 실제로 연관을 가지는 객체의 수
    • 다대일(N:1) ex) 회원(N) : 팀(1)
    • 일대다(1:N) ex) 팀(1) : 회원(N)
    • 일대일(1:1)
    • 다대다(N:N)
  • 연관관계의 주인(Owner) : 객체가 양방향 연관관계일 때 테이블의 외래키를 관리하는 객체

단방향 연관관계

<예제 프로젝트 구상>
1. 회원과 팀이 있다.
2. 회원은 하나의 팀에만 소속될 수 있다.
3. 회원과 팀은 다대일 관계이다.

 

회원(Member)과 팀(Team) 객체의 연관관계

 

@Entity
public class Member {

    @Id @GeneratedValue
    @Column(name = "MEMBER_ID")
    private Long id;

    @Column(name = "USERNAME")// 테이블 칼럼명
    private String username;

    //@Column(name = "TEAM_ID")
    //private Long teamId;
    @ManyToOne
    @JoinColumn(name = "TEAM_ID")
    private Team team;
    
    // getter/setter 생략
}
@Entity
public class Team {

    @Id @GeneratedValue
    @Column(name = "TEAM_ID")
    private Long id;
    private String name;
    // getter/setter 생략
}

Main.java

Team team = new Team();
team.setName("TeamA");
em.persist(team);

Member member = new Member();
member.setName("member1");
member.setTeam(team);
em.persist(member);

// Member 정보를 영속성 컨텍스트에서 찾지 않고, DB에서 찾아오는 쿼리문을 보고싶을 때
em.flush(); // 현재 영속성 컨텍스트의 내용을 모두 DB 쿼리로 날림
em.clear(); // 영속성 컨텍스트 초기화

Member findMember = em.find(Member.class, member.getId());
// (1) Member 객체 일일이 찾아서 넣어줌
//Long findTeamId = findMember.getTeamId();
//Team findTeam = em.find(Team.class, findTeamId);

 // (2) 단방향 매핑 후 조회, (1)을 보완한 것
 Team findTeam = findMember.getTeam();
 
 // (3) 수정
 Team newTeam = em.find(Team.class, 100L); // PK가 100인 팀 객체 찾기
 findMember.setTeam(newTeam); // DB에 외래키 값 변경됨
  • 회원 객체는 Member.team 필드(멤버변수)로 팀 객체와 연관관계를 맺음
  • 회원 객체와 팀 객체는 단방향 관계
    → 회원은 Member.team 필드를 통해 팀을 알 수 있지만, 반대로 팀은 회원을 알 수 없음
    ex) member  team : member.getTeam()
    ex) team  member : x

 

  •  @ManyToOne
    • 다대일(N:1) 관계를 나타내는 매핑 정보
    • 연관관계 매핑 시 사용 필수
    • 속성
      속성 설명 기본값
      optional false로 설정 시 연관된 엔티티가 항상 존재해야 함 true
      fetch 글로벌 패치 전략 설정 FetchType.EAGER
      cascade 속성 전이 기능 사용  
      targetEntity ◾ 연관된 엔티티의 타입 정보 설정
      ◾ 거의 사용하지 않음
      ◾ 컬렉션 사용해도 제네릭으로 타입 정보 알 수 있음
         ex) @OneToMany
              private List<Member> members;
       
  • @JoinColumn
    • 외래 키 매핑 시 사용
    • 생략 가능
    • 속성
      속성
      설명 기본값
      name 매핑할 외래 키 이름 필드명 + _ + 참조하는 테이블의
      기본 키 컬럼명
      ex) team_TEAM_ID
      referencedColumnName 외래 키가 참조하는
      대상 테이블의 컬럼명
      참조하는 테이블의 기본 키 컬럼명
      foreignKey
      (DDL)
      ◾ 외래 키 제약조건 직접 지정
      ◾ 테이블 생성 시에만 사용
       
      unique,
      nullable,
      insertable,
      columnDefinition,
      table
      @Column의 속성과 같음  

 

 

회원(Member)과 팀(Team) 테이블 연관관계

  • 회원 테이블은 TEAM_ID 외래 키로 팀 테이블과 연관관계를 맺음
  • 회원 테이블과 팀 테이블은 양방향 관계
    → 회원 테이블의 TEAM_ID 외래키를 통해 회원과 팀, 팀과 회원 조인 가능
    • 회원(MEMBER)과 팀(TEAM) 조인
      • SELECT * FROM MEMBER M JOIN TEAM T ON M.TEAM_ID = T.TEAM.ID
    • 팀(TEAM)과 회원(MEMBER) 조인
      • SELECT * FROM TEAM T JOIN MEMBER M ON T.TEAM_ID = M.TEAM.ID

 

🔅 객체 연관관계 vs 테이블 연관관계

  • 객체참조(주소)로, 테이블외래 키로 조인을 사용해서 연관관계를 맺는다.
  • 객체의 연관관계는 단방향(A → B (a.b)), 테이블의 연관관계는 양방향(A JOIN B, B JOIN A)이다.
  • 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
    • A → B (a.b)
    • B → A (b.a)

'JPA' 카테고리의 다른 글

[JPA] 다양한 연관관계 매핑  (0) 2022.11.28
[JPA] 연관관계 매핑 - 양방향 연관관계  (0) 2022.08.08
[JPA] 엔티티 매핑  (0) 2022.07.28
[JPA] 준영속 상태  (0) 2022.07.18
[JPA] 플러시(Flush)  (0) 2022.07.18

댓글