객체를 테이블에 맞추어 데이터 중심으로 모델링하면, 협력 관계를 만들 수 없다.
@Entity
public class Member {
// ...
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
}
//팀 저장
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 Team {
// ...
@OneToMany(mappedBy = "team")
List<Member> members = new ArrayList<Member>();
//조회
Team findTeam = em.find(Team.class, team.getId());
int memberSize = findTeam.getMembers().size(); //역방향 조회
가급적 단방향이 좋다.
객체와 테이블이 관계를 맺는 차이
객체의 양방향 관계
테이블의 양방향 연관관계
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
속성 사용XmappedBy
속성으로 주인 지정누구를 주인으로?
여기서는 Member.team이 연관 관계의 주인
양방향 매핑 시 가장 많이 하는 실수
연관 관계의 주인에 값을 입력하지 않음
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
//역방향(주인이 아닌 방향)만 연관관계 설정
team.getMembers().add(member);
em.persist(member);
양방향 매핑 시 연관 관계의 주인에 값을 입력해야 한다.
//연관 관계의 주인에 값 설정
member.setTeam(team);
연관 관계 편의 메서드를 생성하자
// Member.changeTeam()
public void changeTeam(Team team) {
this.team = team;
team.getMembers().add(this);
}
양방향 매핑 시에 무한 루프를 조심하자
toString() 문제
Member.toString
@Override
public String toString() {
return "Member{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", team=" + team +
'}';
}
Team.toString()
@Override
public String toString() {
return "Team{" +
"id=" + id +
", name='" + name + '\'' +
", members=" + members +
'}';
}
System.*out*.println(member);
Json 라이브러리 문제
처음 설계 시 단방향 매핑으로 하고, 양방향은 필요할 때 추가해도 됨
(테이블에 영향을 주지 않음)
연관 관계의 주인을 정하는 기준