연관관계 매핑 기초 - 1 (JPA)
1. 연관관계가 필요한 이유
- 객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력관계를 만들 수 없다.
- 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다.
- 객체는 참조를 사용해서 연관된 객체를 찾는다.
- 테이블과 객체 사이에는 이런 큰 간격이 있다.
2. 단방향 연관관계
package hellojpa;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package hellojpa;
import javax.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
@Entity
public class Member {
@Id
@GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String username;
// @Column(name="TEAM_ID")
// private Long teamId;
@ManyToOne // !!!
@JoinColumn(name="TEAM_ID") // !!!
private Team team;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Team getTeam() {
return team;
}
public void setTeam(Team team) {
this.team = team;
}
}
1) test
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
em.persist(member);
Member findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam();
System.out.println("findTeam = "+findTeam.getName());
3. 양방향 연관관계와 연관관계의 주인
package hellojpa;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
public class Team {
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "team") /// !!!
private List<Member> members = new ArrayList<>(); // !!
...
public List<Member> getMembers() {
return members;
}
public void setMembers(List<Member> members) {
this.members = members;
}
}
1) 객체와 테이블이 관계를 맺는 차이
객체 연관관계 = 2개
- 회원 -> 팀 연관관계 1개 (단방향)
- 팀 -> 회원 연관관계 1개 (단방향)
테이블 연관관계 = 1개
2) 객체의 양방향 관계
- 객체의 양방향 관계는 사실 양방향 관계가 아니라 서도 다른 단방향 관계 2개다.
- 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.
A -> B (a.getB()) classA{ B b; }
B -> A (b.getA()) classB{ A a; }
3) 테이블의 양방향 연관관계
- 테이블은 외래키 하나로 두 테이블의 연관관계를 관리
- MEMBER.TEAM_ID 외래키 하나로 양방향 연관관계 가짐
SELECT * FROM MEMBER M JOIN TEAM T ON M.TEAM.ID = T.TEAM_ID
SELECT * FROM TEAM T JOIN MEMBER M ON T.TEAM.ID = M.TEAM_ID
4) 연관관계의 주인 (Owner)
양방향 매핑 규칙
- 객체의 두 관계중 하나를 연관관계의 주인으로 지정
- 연관관계의 주인만이 외래키를 관리 (등록,수정)
- 주인이 아니쪽은 읽기만 가능
- 주인은 mappedBy 속성 사용 X
- 주인이 아니면 mappedBy 속성으로 주인 지정
5) 누구를 주인으로?
- 외래키가 있는 곳을 주인으로 정함.
- 여기서는 Member.team이 연관관계의 주인
- 1 : 다 중 다가 주인이됨. (외래키가 있는 곳)
출처 : 자바 ORM 표준 JPA 프로그래밍 - 기본편(김영한) 인프런
댓글남기기