객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없습니다.
- 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾습니다.
- 객체는 참조를 사용해서 연관된 객체를 찾습니다.
- 테이블과 객체 사이에는 이런 큰 간격이 있습니다.
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
---
}
@Entity
public class Team{
@Id @GeneratedValue
private Long id;
private String name;
---
}
//팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
//회원 저장
Member member = new Member();
member.setName("member1");
//단방향 연관관계 설정, 참조 저장
member.setTeam(team);
em.persist(member);
//조회
Member findMember = em.find(Member.class, member.getId());
//참조를 사용해서 연관관계 조회
Team findTeam = findMember.getTeam();
//새로운 팀B
Team teamB = new Team();
teamB.setName("TeamB");
em.persist(teamB);
//회원1에 새로운 팀B 설정
member.setTeam(teamB);
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
---
}
@Entity
public class Team{
@Id @GeneratedValue
private Long id;
private String name;
//양방향에서 추가된 부분
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
---
}
//조회
Team findTeam = em.find(Team.class, team.getId());
//역방향 조회가 가능합니다.
int memberSize = findTeam.getMembers().size();
객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개로 이루어져있습니다.
객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 합니다.
테이블은 외래 키 하나로 두 테이블의 연관관계를 관리합니다.
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
객체의 두 관계중 하나를 연관관계의 주인으로 지정합니다.
연관관계의 주인만이 외래 키를 관리합니다.(등록, 수정)
주인이 아닌쪽은 읽기만 가능합니다.
주인은 mappedBy 속성 사용 X
주인이 아니면 mappedBy 속성으로 주인을 지정합니다.
[Reference]