<aside> ❗
연관관계의 주인
: 객체 양방향 연관관계는 관리 주인이 필요** 객체 지향 설계의 목표는 자율적인 객체들의 협력 공동체
를 만드는 것이다. **
객체지향의 사실과 오해 - 조영호
오브젝트 - 조영호
</aside>
<aside> ❗
// 참조 대신에 **외래 키를 그대로 사용**
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@Column(name = "TEAD_ID")
private Long teamId; // 외래키가 들어가게 됨
...
}
@Entity
public class Team {
@Id @GeneratedValue
@Column(name = "Team_ID")
private Long id;
private String name;
}
// 팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
// 회원 저장
Member member = new Member();
member.setName("member1");
member.setTeamId(team.getId());
em.persist(member);
// 조회
Member findMember = em.find(Member.class, member.getId());
// 연관관계 없음
Team findTeam = em.find(Team.class, findMember.getTeamId());
</aside>
<aside> ❗
협력 관계를 만들 수 없다.
테이블은 외래 키로 조인
을 사용해서 연관된 테이블을 찾는다.객체는 참조
를 사용해서 연관된 객체를 찾는다.<aside> ❗
[객체 지향 모델링] - 객체 연관관계 사용
참조 객체를 그대로 저장
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
private int age;
@ManyToOne // N : 1 일 때, N인 곳에 ManyToOne을 사용해야 한다.
@JoinColumn(name = "TEAM_ID")
private Team team;
}
N : 1 일 때, N인 곳에 @ManyToOne을 사용해야 한다.
단방향 연관관계의 경우 ( 1 : N )
N 쪽에 참조할 객체의 참조변수 필드
를 갖는다. (Member가 Team 참조변수를 갖는다.)
이 때 @ManyToOne
애너테이션과 @JoinColumn(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();
<aside> ❗
[연관관계 수정]
// 새로운 팀B
Team teamB = new Team();
teamB.setName("TeamB");
em.persist(teamB);
// 회원1에 새로운 팀 B 설정
member.setTeam(teamB);
</aside>
<aside> ❗
양쪽으로 참조할 수 있게 만드는 것을 양방향 연관관계
테이블 연관관계는 외래키 하나로 양방향이 다 있음
객체가 양방향 연관관계를 가지려면 두 객체 모두 참조 변수를 가져야 한다.
1 : N인 경우 N 쪽에 하나의 참조변수, 1인 쪽에 List<참조변수타입> 선언 후
@OneToMany(mappedBy = “team”) 애너테이션을 붙여준다.
여기서 team은 연관관계에 있는 객체의 참조변수의 이름@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")
// 구현체로 초기화해주는 것이 관례, add할 때 NullPointer 예외가 발생하지 않음
List<Member> members = new ArrayList<Member>();
}
// 조회
Team findTeam = em.find(Team.class, team.getId());
List<Member> memberList = findTeam.getMembers(); // 역방향 조회
객체는 가급적 단방향이 좋다.
</aside><aside> ❗
객체와 테이블간에 연관관계를 맺는 차이를 이해
해야 한다.[객체 연관관계 = 2개] - 단반향 연관관계가 2개가 있는 것 (양방향)
** 참조가 양쪽 객체에 있어야 한다. **
[테이블 연관관계 = 1개]
<aside> ❗
객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개다
양방향으로
참조
하려면 단방향 연관관계를 2개 만들어야 한다.
// A -> B
class A {
B b;
}
// B -> A
class B {
A a;
}
</aside>
<aside> ❗
외래 키 하나로 두 테이블의 연관관계를 관리
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
</aside>
<aside> ❗
</aside>