-
[JPA] 다양한 연관 관계 매핑 ( N:1 / 1:N / 1:1 / N:M )DEV/JPA 2024. 4. 4. 03:43
* 정보전달의 목적이 아닌 개인 스터디 정리 글 입니다.
강의 : 인프런 <자바 ORM 표준 JPA 프로그래밍 기본편>
교육자 : 김영한
연관관계 매핑시 고려사항
- 다중성
- 다대일 : @ManyToOne
- 일대다 : @OneToMany
- 일대일 : @OneToOne
- 다대다 : @ManyYoMany
- 단방향, 양방향
- 테이블 : 외래키로 양쪽 조인 가능, 방향개념 없음
- 객체 : 참조용 필드가 있는 쪽으로만 참조 가능, 한쪽만 참조하면 단방향, 양쪽 서로 참조하면 양방향
- 연관관계의 주인
- 외래키를 관리하는 참조가 주인
- 주인의 반대편은 외래키에 영향을 주지않고 단순 조회만 가능
1. 다대일 (N:1)
: 외래키있는곳에 객체 참조 걸어주기1-1. 다대일 단방향
- 가장 많이 사용하는 연관관계
- 다대일의 반대는 일대다
1-2. 다대일 양방향- 외래키가 있는 쪽이 연관관계의 주인
- 양쪽을 서로 참조하도록 개발
- 반대쪽은 객체 추가만함. 읽기만 가능. 테이블 영향없음2. 일대다 (1:N)
2-1. 일대다 단방향
- 1이 연관관계의 주인- N쪽에 외래키가 있음
- 객체와 테이블의 차이 때문에 반대편 테이블의 외래키를 관리하는 구조
* 유의사항
- team을 insert 했는데 member의 update쿼리가 추가됨
- Joincolumn 어노테이션을 넣지않으면 하이버네이트가 중간테이블을 하나 추가함일대다 단방향 매핑의 단점
- 엔티티가 관리하는 외래키가 다른(상대) 테이블에 있음
- 연관관계 관리를 위해 추가로 UPDATE SQL이 실행됨
=> 일대다 단방향 매핑보다 다대일 양방향 매핑을 사용을 권장
2-2. 일대다 양방향
: 공식적으로는 존재하지않고 야매로 속성을 넣어서 읽기전용으로 만들어야함- @JoinColumn(insertable=false, updateable=false) 이와 같이 읽기 전용 필드를 사용해서 양방향 처럼 사용
=> 다대일 양방향 사용을 권장
3. 일대일 (1:1)
: 일대일 관계는 그 반대도 일대일- 주 테이블이나 대상 테이블 중 외래키 선택 가능
- 외래키에 데이터베이스 유니크 제약조건 추가
3-1. 주 테이블에 외래키 단방향
- 다대일 단방향 매핑과 유사
3-2. 주 테이블에 외래키 양방향
- 다대일 양방향 매핑 처럼 외래키가 있는 곳이 연관관계의 주인
- 반대편은 mappedBy 적용
3-3. 대상 테이블에 외래키 단방향
- 단방향 관계는 JPA 지원하지 않음
- 양방향 관계는 지원
3-4. 대상 테이블에 외래키 양방향
- 일대일 주 테이블에 외래키 양방향과 매핑 방법이 같음 (테이블 반대로 뒤집는 차이)
* 장단점 정리
- 주 테이블에 외래키 : 객체지향 개발자 선호, JPA 매핑 편리
- 장점 : 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인가능
- 단점 : 값이 없으면 외래키에 null허용
- 대상 테이블에 외래키 : 데이터베이스 개발자 선호 (테이블 변경할 변수가 적음)
- 장점 : 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지가능
- 단점 : 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨
4. 다대다(N:M)
: 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없음- 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어야함
- 객체는 컬렉션을 사용해서 객체 2개로 다대다 관계 가능
- @ManyToMany 사용, @JoinTable로 연결 테이블 지정
- 다대다 매핑 : 단방향, 양방향 가능
다대다 => 실무에서 쓰면 안된다 ?
이유
: 연결테이블이 필요한데 실무에서는 단순하게 연결만 하고 끝나지않음. ( 테이블에 계속 필요한 데이터가 추가될 수 있음 )
따라서 일대다, 다대일로 풀어서 사용할것. 중간테이블을 엔티티로 승격!ex) Member와 Product 사이의 중간테이블 (Memeber_Product)을 Order 테이블로 바꾸어 엔티티로 만들기
* 주요 어노테이션 속성 설명
@JoinColumn : 외래키 매핑시 사용
속성 설명 기본값 name 매핑할 외래 키 이름 필드명 + _ + 참조하는 테 이블의 기본 키 컬럼명 referencedColumnName 외래 키가 참조하는 대상 테이블의 컬럼명 참조하는 테이블의 기본 키 컬럼명 foreignKey(DDL) 외래 키 제약조건을 직접 지정할 수 있다. 이 속성은 테이블을 생성할 때만 사용한다. unique
nullable
insertable
updatable
columnDefinition
table@Column의 속성과 같다. @ManyToOne : 다대일 관계 매핑
속성 설명 기본값 optional false로 설정하면 연관된 엔티티가 항상 있어야 한다. TRUE fetch 글로벌 페치 전략을 설정한다. - @ManyToOne=FetchType.EAGER
- @OneToMany=FetchType.LAZYcascade 영속성 전이 기능을 사용한다. targetEntity 연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거 의 사용하지 않는다. 컬렉션을 사용해도 제네릭으로 타 입 정보를 알 수 있다. @OneToMany : 일대다 관계 매핑
속성 설명 기본값 mappedBy 연관관계의 주인 필드를 선택한다. fetch 글로벌 페치 전략을 설정한다. - @ManyToOne=FetchType.EAGER
- @OneToMany=FetchType.LAZYcascade 영속성 전이 기능을 사용한다. targetEntity 연관된 엔티티의 타입 정보를 설정한다. 이 기능은 거 의 사용하지 않는다. 컬렉션을 사용해도 제네릭으로 타 입 정보를 알 수 있다. 'DEV > JPA' 카테고리의 다른 글
[JPA] 프록시와 연관관계 관리 (즉시로딩/지연로딩/영속성전이/고아객체) (0) 2024.04.29 [JPA] 고급매핑 - 상속관계 매핑 (0) 2024.04.05 [JPA] 연관관계 매핑 기초 (0) 2024.03.29 [JPA] 엔티티 매핑 (0) 2024.03.07 [JPA] 영속성 관리 (0) 2024.02.22 - 다중성