객체와 관계형 db 테이블이 어떻게 매핑되는지 이해하기!
객채 연관관계와 db 테이블 연관관계 비교
객체 | db 테이블 |
---|---|
참조(주소)로 연관관계 맺음 | fk로 연관관계 맺음 |
참조를 사용하는 객체의 연관관계는 단방향 | db 테이블의 연관관계는 양방향 |
방향 : 단방향, 양방향
db 테이블은 외래키 하나로 양쪽 테이블 조인 가능 -> 방향 나눌 필요 없음.
but 객체는 참조용 필드 있는 객체만 다른 객체 참조 가능.
두 객체 사이 하나의 객체만 참조용 필드 갖고 참조하면 단방향, 두 객체 모두 각각 참조용 필드 갖고 참조하면 양방향 관계하고 함.
단방향 관계
회원 객체와 팀 객체의 관계
회원은 member.team 필드 통해 팀 알 수 있지만 팀 객체로는 소속된 회원 알 수 없음.
member -> team 조회 가능하지만, team -> member 접근 필드는 없음.
다중성
일대일 (1:1)
다대일 (N:1)
post(게시글)와 board(게시판)
@Entity
public class Post {
@Id @GeneratedValue
@Column(name = "POST_ID")
private Long id;
@Column(name = "TITLE")
private String title;
@ManyToOne
@JoinColumn(name = "BOARD_ID")
private Board board;
//...
}
---------------------------
@Entity
public class Board {
@Id @GeneratedValue
private Long id;
private String title;
// 양방향일 경우
@OneToMany(mappedBy = "board")
List<Post> posts = new ArrayList<>();
//...
}
다대일 단방향
post에서 board 참조
N쪽에 @ManyToOne 추가 (N에 fk 있어야 함.)
다대일 양방향
서로 참조.
연관 관계 주인이 fk 관리.
양방향일 경우 @OneToMany 추가하고 연관 관계 주인을 mappedBy로 지정.
(연관관계의 주인은 mappedBy 사용 x)
참조 당하는 쪽에서 읽기만 가능.
외래키 있는 쪽(N)이 연관 관계 주인.
일대다(1:N)
다대일의 기준은 연관 관계 주인인 다(N) 쪽에 둔 것이고, 일대다의 기준은 연관관계의 주인을 일(1) 쪽에 둔 것.
일대다(1:N) 단방향은 안쓰는게 좋음.
대신 객체관계를 조금 포기하고 다대일 양방향 매핑을 사용하자.
<질문>
연관 관계의 주인에 대해 설명하고 어떤식으로 지정해야 하는지 설명해주세요.
두 객체가 양방향 관계(단방향 관계 2개)일 때 연관 관계 주인을 지정해야 한다.
두 단방향 관계 중 제어의 권한(저장, 수정, 삭제) 갖는 실질적 관계 어떤 것인지 jpa에게 알려주는 것이다.
주인은 crud 할 수 있지만 주인 아니면 조회만 가능하다.
외래 키가 있는 곳(다대일일 경우 다)을 연관 관계 주인으로 정하면 된다.
다대다(N:M) 관계는 왜 사용하지 않는 것이 좋을까요? 어떤식으로 해결할 수 있을까요?
<지양 이유>
관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계 표현할 수 없고, 연결 테이블 있어야 함.
jpa에서는 @ManyToMany 어노테이션 사용할 수 있지만 한계 존재한다.
1) 연결 테이블 생성해 주지만 묵시적으로 생성하기 때문에 예상하지 못한 쿼리 나갈 수 있음.
2) 연결 테이블 자체에는 매핑 정보만 넣을 수 있고, 추가 데이터를 넣을 수 없음.
<극복>
연결 테이블용 엔티티를 추가하여 (연결 테이블을 엔티티로 승격시킴) 일대다, 다대일 관계로 풀어서 사용하는 것이 좋다.
<참고>
https://jeong-pro.tistory.com/231
https://velog.io/@conatuseus/연관관계-매핑-기초-1-i3k0xuve9i
https://jyami.tistory.com/21
https://jdm.kr/blog/141
일대다: https://ym1085.github.io/jpa/JPA-일대다/
다대다: https://ict-nroo.tistory.com/127