4. [JPA] 연관관계 매핑
안녕하세요 현우입니다. 이번 포스팅은 [ 연관관계 매핑에대한 이해 ] 입니다.
참고도서
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 연관 관계를 설정해 줍니다.
-
테이블은 외래키 조인
-
객체는 참조 사용
@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