객체지향 설계의 목표는 자율적인 객체들의 협력 공동체를 만드는 것이다.
객체지향의 사실과 오해, 조영호
// 참조 대신 외래 키를 그대로 사용하는 방식
// Member
@Entity
public class Member {
@Id @GeneratedValue
private Long id;
@Column(name = "USERNAME")
private String name;
@Column(name = "TEAM_ID")
private Long teamId;
...
}
// Team
@Entity public class Team {
@Id @GeneratedValue
private Long id;
private String name;
...
}
이외에도 아래와 같은 방식으로 모델링할 수 있음
➡️ 객체를 테이블에 맞추어 데이터 중심으로 모델링하면 협력 관계를 만들 수 없음
왜냐하면, 연관된 테이블/객체를 찾는 방식에 있어서 아래와 같은 큰 차이가 있기 때문
1) 객체 연관관계 사용
@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;
...
}
2) ORM 매핑
// 팀 저장
Team team = new Team();
team.setName("TeamA");
em.persist(team);
// 회원 저장
Member member = new Member();
member.setName("member1");
member.setTeam(team); // 단방향 연관관계 설정, 참조 저장
em.persist(member);
3) 참조로 연관관계 조회 - 객체 그래프 탐색
// 조회
Member findMember = em.find(Member.class, member.getId());
// 참조를 사용해서 연관관계 조회
Team findTeam = findMember.getTeam();
4) 연관관계 수정
// 새로운 팀 B
Team teamB = new Team();
teamB.setName("TeamB");
em.persist(teamB);
// 회원1에 새로운 팀 B 설정
member.setTeam(teamB)
// Member 엔티티는 단방향과 동일
@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;
...
}
// Team 엔티티는 컬렉션 추가
@Entity
public class Team {
@Id @GeneratedValue
priavte 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(); // 역방향 조회
mappedBy
... 처음에는 이해하기 어려움// A 객체
class A {
B b;
}
// B 객체
class B {
A a;
}
MEMBER.TEAM_ID
외래 키 하나로 양방향 연관관계 가짐 (양쪽으로 조인할 수 있음) ```
SELECT FROM MEMBER M JOIN T ON M.TEAM_ID = T.TEAM_ID외래 키 하나로 양방향 연관관계를 가지므로, **외래 키를 관리하는 주체도 하나**
![](https://velog.velcdn.com/images/aoqlsdl/post/5b8ab040-d6b9-4f9d-bc4a-44424ac3affc/image.png)
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);
➡️ 양방향 매핑시 연관관계의 주인에 값을 입력해야 함 (순수한 객체 관계를 고려하면 항상 양쪽 모두 값을 입력해야 함)
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
team.getMembers().add(member);
// 연관관계의 주인에 값 설정
member.setTeam(team);
em.persist(member);
toString()
, lombok, JSON 생성 라이브러리)