연관관계 매핑 기초

gustjtmd·2022년 5월 24일
0

목표

'목표'

- '객체와 테이블 연관관계의 차이를 이해'

- '객체의 참조와 테이블의 외래 키를 매핑'

- 용어 이해
	- '방향' : 단방향,양방향
    - '다중성' : 다대일(N:1), 일대다(1:N), 일대일(1:1), 다대다(N:M)이해
    - '연관관계의 주인' - 객체 양방향 연관관계는 관리 주인이 필요

연관관계가 필요한 이유

객체지향 설계의 목표는 자율적인 객체들의 협력 공동체를 만드는 것이다.
'예제 시나리오'

1. 회원과 팀이 있다.

2. 회원은 하나의 팀에만 소속될 수 있다.

3. 회원과 팀은 다대일 관계다.

객체를 테이블에 맞추어 모델링

'객체를 테이블에 맞추어 데이터 중심으로 모데링하면, 협력 관계를 만들 수 없다.'

1. 테이블은 외래 키로 조인을 사용해서 연관된 테이블을 찾는다.
2. 객체는 참조를 사용해서 연관된 객체를 찾는다.
3. 테이블과 객체 사이에는 이런 큰 간격이 있다

'객체를 테이블에 맞추어 모델링'(참조 대신에 외래 키를 그대로 사용)

@Entity
public class Member {
	 @Id @GeneratedValue
	 private Long id;
     
	 @Column(name = "USERNAME")
	 private String name;

	@Column(name = "TEAM_ID")
 	private Long teamId;}
 
 @Entity
 public class Team {

	@Id @GeneratedValue
	 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, team.getId());

단방향 연관관계 객체 지향 모델링

'객체 지향 모델링'(객체의 참조와 테이블의 외래 키를 매핑)

@Entity
 public class Member {
 
	 @Id @GeneratedValue
	 private Long id;
 
	 @Column(name = "USERNAME")
	 private String name;
	 private int age;
     
     // @Column(name = "TEAM_ID")
	 // private Long teamId;

	 @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);

양방향 연관관계와 연관관계의 주인

양방향 매핑

'Member 엔티티는 단방향과 동일'

@Entity
 public class Member {
 
	 @Id @GeneratedValue
	 private Long id;
 
	 @Column(name = "USERNAME")
	 private String name;
	 private int age;
     
     // @Column(name = "TEAM_ID")
	 // private Long teamId;

	 @ManyToOne
	 @JoinColumn(name = "TEAM_ID")
	 private Team team;========================================================================

'Team 엔티티는 컬렉션 추가'

@Entity
public class Team {
 
 	@Id @GeneratedValue
 	private 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

'객체와 테이블이 관계를 맺는 차이'

- '객체 연관관계 = 2개'
	- 회원 -> 팀 연관관계 1(단방향)
    --> 회원 연관관계 1(단방향
    
- '테이블 연관관계 = 1개'
	- 회원 <-> 팀의 연관관계 1(양방향)

객체와 테이블이 관계를 맺는 차이

'객체의 양방향 관계는 사실 양방향 관계가 아니라 서로 다른 단방향 관계 2개다'
- 객체를 양방향으로 참조하려면 단방향 연관관계를 2개 만들어야 한다.!

'테이블은 외래 키 하나로 두 테이블의 연관관계를 관리'

MEMBER.TEAM_ID 외래 키 하나로 양방향 연관관계를 가짐(양쪽으로 조인할 수 있다)

'양방향 매핑 규칙'
	- 객체의 두 관계중 하나를 연관간계의 주인으로 지정
    
    - '연관관계의 주인만이 외래 키를 관리(등록 수정)'
    
    - '주인이 아닌쪽은 읽기만 가능'
    
    - 주인은 mappedBy 속성 사용X
    
    - 주인이 아니면 mappedBy 속성으로 주인 지정
    
* 외래 키가 있는 곳을 주인으로 정해라

양방향 매핑시 가장 많이 하는 실수

'연관 관계의 주인에 값을 입력하지 않음'

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)


'단방향 매핑만으로도 이미 연관관계 매핑은 완료'
- 양방향 매핑은 반대 방향으로 조회(객체 그래프 탐색) 기능이 추가된 것 뿐

- JPQL에서 역방향으로 탐색할 일이 많음

- 단방향 매핑을 잘 하고 양방향은 필요할 때 추가해도 됨(테이블에 영향을 주지 않음)
profile
반갑습니다

0개의 댓글