Spring Boot JPA 3 - 양방향 매핑 , 연관관계 테이블

UnKnown12·2022년 12월 8일
0

Spring Boot

목록 보기
7/13

📌 양방향 매핑

객체참조

  • 외래 키(FK) 역할을 객체 참조를 통해 선언하는 역할

  • 현재 객체는 Member 가 Team을 가졌으나,
    Team 은 Member를 가지지 못한다

  • 이것이 객체 참조와 외래키 (FK ) 의 가장 큰 차이점

  • 테이블은 FK만 있으면 양쪽에 연관관계를 알 수 있다.

// TEAM 테이블 
	@OneToMany(mappedBy = "team") // Member테이블의 변수명과 동일해야한다
	private List<Member> member = new ArrayList<Member>();


// Member 테이블 
	@ManyToOne	// Team 클래스에서 "하나" 가져오기 
	@JoinColumn(name = "TEAM_ID") // 연관 컬럼 이어주기 , TEAM 명칭과 반드시 동일해야한다 
	private Team team;
  • Member -> Team = N개 -> 1개 = @ManyToOne
  • Team -> Member = 1개 -> N개 = @oneToMany

📌 테이블 연관관계

  • 관계 1개
    = Member테이블 입장에서 Team 테이블로 조인 가능
    또한, Team 테이블 입장에서 Member 테이블 조인이 가능하다

📌 객체 연관관계

  • 관계 2개
    Member 객체 에서 -> Team 객체로 연관관계 1개 ( 단 방향 )
    Team 객체에서 -> Member객체로 가는 연관관계 1개 ( 단 방향 )
    = 따라서 관계는 2개

  • 양방향 매핑이긴 하나
    사실은 단방향 매핑이 2개가 있는 것.

📌 관리의 딜레마

  • 둘 중 하나로 외래키를 관리해야한다 ( 둘다는 못함 )
  • 그렇다면 누가 관리 등록 수정을 담당해야하는가?

객체 입장

  • Member 에서 Team 으로 가는 Team 참조 값과, ( Member to Team )
    Team 에서 Member로 가는 Member 참조 값이 있다. ( Team to Member )

  • 그런데 만약
    Member 에서 Team 값이 수정 되었을 때, Member 테이블의 TEAM_ID 가 수정되어야 하는지,
    Team 에서 Member 값을 수정해야하는지 딜레마 가 있다.

DB 입장

  • 양방향 테이블에서 수정이 발생할 때,
    DB입장에서는 Member 테이블에 있는 TEAM_ID 만 Update 시키면 된다.

  • 단, 이때 양방향 매핑 규칙(연관관계의 주인) 을 따라야 한다.

📌 연관관계의 주인

  • 객체의 두 관계 중 하나를 연관관계의 주인으로 지정

  • 오직 연관관계의 주인만이 외래 키를 관리 및 수정이 가능하다.
    ( 주인이 아니라면 읽기 전용 )

  • 주인은 @MappedBy 속성을 사용하지 않는다.

  • 따라서 Member 테이블에서 수정하면
    TEAM 테이블 은 수정사항이 반영이 되는 구조.

📌 양방향 연관관계의 주의사항

  • 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정해야한다
  • 연관관계 편의 메소드를 생성하라
  • 양방향 매핑시 무한루프에 조심하자
    ex) toString, lombok lib 조심할 것
member.setTeam(team);

team.getMember().add(member);

하위 테이블에도 TEAM 단방향 추가 +
상위 테이블에도 MEMBER 단방향 추가 +

  • 2개중 하나라도 방향이 선언되지 않으면
    DB 구조가 분열될 수 있다.
    따라서 1개의 메소드로
    단향뱡 2개를설정함으로써 해결한다

❗ lombok 을 이용해 단방향 2개 동시 설정하기

@Setter( value = AccessLevel.NONE)

  • 세터 기능 중지

MEMBER 테이블

	@ManyToOne	// Team 클래스에서 "하나" 가져오기 
	@JoinColumn(name = "TEAM_ID") // 연관 컬럼 이어주기 , TEAM 명칭과 반드시 동일해야한다 
	@Setter(value = AccessLevel.NONE) // lombok 옵션 setter 설정을 막는다 
	private Team team;

    	// 단방향 2개 설정 메소드 
	public void changeTeam(Team team) {
		this.team = team;
		team.getMember().add(this);
		// = team.getMember().add(member);
	}
}

TEAM 테이블

  • TEAM 테이블에도 마찬가지로
    단방향 설정을 해야한다
	public void addMember(Member member) {
		member.setTeam(this);
		this.member.add(member);
	}

📌 양방향 매핑 정리

  • 단 방향 매핑 만으로도 연관관계 매핑을 완료가 된다
    양 방향 매핑은 반대 방향으로 조회기능이 추가된 것 뿐이다.

  • 양방향 사용이유 = JPQL 에서 역방향으로 탐색(조회)할 일이 많음
    단 방향매핑을 필수로 하되, 양 방향매핑은 필수적이지 않다
    ( 테이블에 영향을 주지않기에 필요할 경우에만 양 방향매핑 기능을 추가한다 )

📌 연관관계의 주인을 정하는 기준

  • 연관관계의 주인은 외래 키(FK) 의 위치를 기준으로 정해야 한다
  • 비지니스 로직을 기준으로 연관관계의 주인을 선택하면 안된다
profile
Hyobin12

0개의 댓글