⚡ 생각대로 살지 않으면 사는대로 생각한다.
⚡ 나는 어차피 잘 될 놈이다. 이미 잘 되고 있고, 계속해서 잘 되고 있다.
테이블 연관관계는 앞에서 봤던 단방향 매핑에서 봤던 것과 바뀐 게 없이 똑같다.
테이블은 PK,FK를 맺어주면 방향이란 개념이 필요없다. 그냥 다 알 수 있다.
문제는... 객체..
Member에서 Team은 참조가능하지만, Team에서는 Member를 참조를 할 수 있는 방법이 없었다. Team에서 List members
를 넣어줌으로 갈 수 있게 되었다.
단방향에서는 Member를 수정했는데, 양방향 매핑에서 Team쪽도 수정을 하면, Team에서 아래와 같이 코드를 작성해주면 된다.
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
@OneToMany(mappedBy = "team") : Member 클래스에서 변수 team으로 선언된 컬럼과 매핑하겠다.
Member 참고.
@ManyToOne @JoinColumn(name = "TEAM_ID") private Team team;
그리고
private List<Member> members = new ArrayList<>();
이와 같은 코드에서 members에 new ArrayList<>();
로 초기화 해주는 것은 관례라고 한다. 그렇게 해야 add
할 때 nullpointException
이 뜨지 않기 때문이다.
양방향 연관관계를 맺어주면 아래와 같이 코드 작성이 가능하다.
Member findMember = em.find(Member.class, member.getId());
List<Member> members = findMember.getTeam().getMembers();
객체는 가급적이면 단방향이 좋다. 양방향 매핑을 하게되면 신경 쓸 것이 많다..
위의 @OneToMany(mappedBy = "team")
에서의 mappedBy
Team과 Member를 가정
단방향 연관관계가 사실 두 개가 있는 것.
테이블은 FK 하나로 테이블의 연관관계가 끝난다. 하지만, 객체는 참조가 서로에게 있어야 한다(단방향 두개)
객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개다.
객체를 양방향으로 참조하려면 아래와 같이 단방향 연관관계를 2개 만들어야 한다.
A -> B (a.getB())
class A {
B b;
}
B -> A (b.getA())
class B {
A a;
}
SELECT *
FROM MEMBER M
JOIN TEAM T ON T.TEAM_ID = T.TEAM_ID
SELECT *
FROM TEAM T
JOIN MEMBER M ON T.TEAM_ID = M.TEAM_ID
테이블의 FK로 가지고 있는 TEAM_ID(FK)를 update하려면, Member 객체가 가지고있는 Team team
을 통해서 update해야하는지, Team 객체가 가지고있는 List members
로 update해야하는지 헷갈린다.
따라서 둘 중 하나로 외래 키를 관리해야하는데, 이 외래키를 관리하는 객체
를 연관관계의 주인(Owner)이라고 한다.
@Entity
public class Member {
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team;
@Entity
public class Team {
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
이 두 객체에선 Member가 연관관계의 주인(Owner)이다.
mappedBy가 적힌 곳은 등록,수정이 불가능하고, 읽기(조회)만 가능하다.
영한좌의 무수한 프로젝트를 깔끔하게 뽑아낸 기준... 설계, 성능이 깔끔해진다.
아웅 재밌다.
-끝-