웹개발/Hibernate(JPA)

4. [JPA] 연관관계 매핑

꿈뻑이의 코딩스토리 2020. 4. 1. 15:06

 

안녕하세요 현우입니다. 이번 포스팅은 [ 연관관계 매핑에대한 이해 입니다. 

 

참고도서

http://acornpub.co.kr/book/jpa-programmig

 

자바 ORM 표준 JPA 프로그래밍

JPA 기초 이론과 핵심 원리, 그리고 실무에 필요한 성능 최적화 방법까지 JPA에 대한 모든 것

www.acornpub.co.kr


 

객체지향 언어와 관계형 데이터베이스(RDBMS)의 연관관계 차이는 무엇일까요?

 

  • 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾습니다.

 

  • 객체는 객체 참조를 사용해서 연관된 객체를 찾습니다.

 

 객체와 관계형 DB에는 이러한 큰 간격이 있습니다. 그렇타고 해서 연관관계를 맺지 않고 TEAM과 MEMBER을 조회한다면 어떻게 될까요? 쉽게 이해하기 위해 한가지 예를 들어보겠습니다. 

 

아래는 회원과 팀의 클래스입니다.

 

Member.class

@Entity
public class Member {

  @Id @GeneratedValue
  private Long id;

  @Column(name = "USERNAME") 
  private String name;

  @Column(name = "TEAM_ID")
  private Long teamId;
  ...
  }

 

Team.class

@Entity
public class Team {

  @Id @GeneratedValue
  private Long id;
  private String name;
  ...
  }

 

아래는 팀과 회원을 저장하는 코드입니다.

//팀 저장
Team team = new Team();
team.setName("wooteco"); 
em.persist(team);

//회원 저장
Member member = new Member();
member.setName("conas");
member.setTeamId(team.getId());
em.persist(member);

 

이제 회원의 팀을 찾아보겠습니다.

Member findMember = em.find(Member.class, member.getId());

Long findTeamId = findMember.getId();
Team findTeam = em.find(Team.class, findTeamId);

 

연관관계가 없다면  회원이 속한 팀번호를 가지고 오기 위해 team의 쿼리문을 따로 작성해야 되고

member 를 꺼내오고 id를 가져와서 다시 팀을 가져와야 하는 객체지향스럽지 않은 코드가 됩니다. 

 

 

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

 

 

이를 해결하기 위해 *ManyToOne 연관 관계를 설정해 줍니다. 

 

  • 테이블은 외래키 조인

  • 객체는 참조 사용

 

image

 

@Entity
@Getter
@Setter
class Member{
  @Id 
  private Long member_id;

  // FK와 매핑해야된다
  @ManyToOne
  @JoinColumn(name = "team_id")
  private Team team;
}


@Entity
@Getter
@Setter
class Team{
   @Id @GeneratedValue
    private Long Team_id;
    private String name;
    private String member;
}

@Entity
@Getter
@Setter
class Member{
	@Id @GeneratedValue
    @Column(name="member_id")
    private Long id;

    private String name;

    @ManyToOne
    @JoinColumn(name = "team_id")
    private Team teamId;
}


------------------------------Main.class-----------------------------


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

  /** 매핑 **/
  member.setTeamId(team);
  em.persist(member);

  em.flush() // 디비에 쿼리를 전부날린다
  em.clear() //영속성컨텍스트 초기화


  /** find **/
  Member findmember = em.find(Member.class, member.getId());
  Team findTeam = findMember.getTeamId();

}

 

출력 결과 

이와 같이 JAVA에서 @ManyToOne을 사용하여 연관관계를 매핑시키면 JPA가 ENTITY 객체를 확인 후 DB에 JOIN 회원과 팀클래스를 JOIN 하여 조회 쿼리문을 날려줍니다.

 

그렇다면 ManyToOne와 JoinCoulmn 은 무엇일까요?

 

@ManyToOne, @JoinColumn


@ManyToOne: 다대일(N:1) 관계라는 매핑 정보입니다. 위에서 봤던 회원과 팀은 다대일 관계입니다. 연관관계를 매핑할 때 이렇게 다중성을 나타내는 어노테이션을 필수로 사용해야 합니다.

속성 기능 기본값
optional false로 설정하면 연관된 엔티티가 항상 있어야 한다 true
fetch 글로벌 패치 전략을 설정한다. 
(자세한 내용)http://bitly.kr/Zdce9PLoH1c
@ManyToOne=FetchType.EAGER
@OneToMany=FetchType.LAZY
cascade 영속성 전이 기능을 사용한다.
(자세한 내용)http://bitly.kr/75vGWfVhNy
 
targetEntity 연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거의 사용하지 않음  

 

@JoinColumn: 외래 키를 매핑할 때 사용합니다.(생략가능)

속성 기능 기본값
name 매핑할 외래 키 이름 필드명 + _ +참조하는 테이블의 기본키 컬럼명
referenceColumnName 외래키가 차조하는 대상 테이블의 컬럼명 참조하는 테이블의 기본키 컬럼명
foreignKey(DDL) @Column 속성과 같다.
unique
nullable
insertable
updatable
columnDefinition
table

 

 


용어 이해

  • 방향 : 단방향 양방향

  • 다중성 : 다대일, 일대다, 일대일, 다대다 (관계형 DB)

  • 연관관계의 주인(Owner): 객체 양방향 연관관계 주인이 필요

 

코드 자세히 보기

https://github.com/HyeonWuJeon/KimYoungHan-JPA

 

HyeonWuJeon/KimYoungHan-JPA

자바 ORM표준 JPA 프로그래밍 책 정리 및 예제 작성. Contribute to HyeonWuJeon/KimYoungHan-JPA development by creating an account on GitHub.

github.com

추가 학습 자료

 

https://www.inflearn.com/course/ORM-JPA-Basic

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그�

www.inflearn.com