다양한 연관관계 매핑(1) - slahsk/study GitHub Wiki
객체 양방향 관계에서 연관관계의 주인은 항상 다쪽이다.
@Entity
public class Member{
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
...
}
@Entity
public class Team{
@Id
@GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
}Member.team으로 팀 엔티티를 참조할 수 있지만
반대로 팀에서는 회원을 참조하는 필드가 없다. 따라서 회원과 팀은 다대일 단방향 연관관계이다.
@Entity
public class Member{
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
private String username;
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
public void setTeam(Team team){
this.team = team;
//팀의 멤버중에 자기 자신이 없으면 추가
if(!team.getMembers().contain(this)){ //양쪽에 작성되어 있기에 무한루프 방지
team.getMembers().add(this);
}
}
...
}
@Entity
public class Team{
@Id
@GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
@OneToMay(mappedMy="team")
private List<Member> members = new ArrayList<>();
//
private void addMember(Member member){
this.members.add(member);
//멤버의 팀이 자기자신이 아니면 멤버에 팀 추가
if(member.getTeam() != this){//양쪽에 작성되어 있기에 무한루프 방지
member.setTeam(this);
}
}
}양방향은 외래 키가 있는 쪽이 연관관계의 주인이다.
양방향 연관관계는 항상 서로를 참조해야한다.
항상 서로 참조하게 하려면 연관관계 편의 메소드를 작성하는것디 좋은데
setTeam(), addMember() 메소드가 편의 메소드들이다.
편의 메소드는 한 곳에서만 작성하거나 양쪽에 다 작성할 수 있는데, 양쪽에 다 작성하면 무한루프에 빠지므로 주의해야한다.
일대다 관계는 엔티티를 하나이상 참조할 수 있다.(Collection, List, Map, Set)
@Entity
public class Member{
@Id
@GeneratedValue
@Column(name="MEMBER_ID")
private Long id;
private String username;
...
}
@Entity
public class Team{
@Id
@GeneratedValue
@Column(name="TEAM_ID")
private Long id;
private String name;
//member 마다 각각의 외래키를 가지고 있다. 본인이 아닌 다른테이블에 관리
@OneToMay
@JoinColumn(name = "TEAM_ID")
private List<Member> members = new ArrayList<>();
}본인 테이블에 외래 키가 있으면 엔티티의 저장과 연관관계 처리를 INSERT SQL 한 번으로 끝낼 수 있지만, 다른 테이블에 외래 키가 있으면 연관관계 처리를 위한 UPDATE SQL을 추가로 실행해야 한다.
Mmeber member1 = new Member("member1");
Mmeber member2 = new Member("member2");
Team team1 = new Team("team1");
team1.getMembers().add(member1);
team1.getMembers().add(member2);
//팀 정보가 디비에 없다
//멤버 입력후 팀이 입력후 member 에 팀정보가 업데이트 가 실행 된다.
em.perist(member1);
em.perist(member2);
em.perist(team1);
transaction.commit();일대다 단방향 매핑보다는 다대일 양방향 매핍을 사용하자 일대다 단뱡향 은 다른 테이블에서 외래키를 관리해야 한다.
성능 문제도 있지만 괸리도 ?? 부담스럽다.
다대일 방향 매핍을 사용