관계별 연관관계 매핑
다대일 (N:1) : 가장 기본적인 관계 , 가장 많이 , 주로 사용하는 관계.
단방향 매핑으로 설계하고 필요시에 양방향 매핑한다. 연관관계의 주인은 언제나 N.
일대다 (1:N) : 일대다로 매핑하는 것보다 다대일로 매핑. (사용 X)
일대일 (1:1) : 어느 테이블에나 외래 키를 넣을 수 있다. 외래 키에 DB 유니크 제약조건이 추가.
다대다 (N:N) : 실무에서 사용 ( X ) , 연결 테이블을 생성해서 다대다 -> 다대일 , 일대다 관계로 변경
편리해 보이지만 실무에서 사용 X , 연결 테이블이 연결만 하고 끝나지 않고 주문시간 , 수량 같은 데이터가 들어옴
-> 연결테이블용 엔티티를 새로 추가. @ManyToMany 를 @ManyToOne & @OneToMany 로 변경.
-> 새로운 연결 테이블에 GenerateValue 로 의미없는 PK 설정해주는 것이 이점 O
-> 모든 테이블에 PK 에 GenerateValue 생성. (의미 없어도 괜찮다)
상속관계 매핑
- Inheritance 속성을 이용해서 조인 전략, 단일 테이블 전략, 구현 클래스마다 테이블 전략 으로 설정이 가능하다.
- 관계형 DB 에는 상속 관계가 존재하지 않는다. -> 슈퍼 / 서브타입 관계라는 모델링 기법이 객체 상속과 유사
※ 조인 전략
- 정규화된 모델링 방법 , JPA와 가장 유사한 방법
- ITEM 테이블에 공통적인 속성을 넣어두고 , DTYPE 을 통해 ALBUM,MOVIE,BOOK 을 구분한다.
public class Items {
@Id @GeneratedValue
private Long id;
private String name;
private int price;
}
@Entity
public class Album extends Items{
private String artists;
}
- 다음과 같이 extends 를 통해 Items 를 상속받아서 조인 전력을 사용해도 쿼리문을 확인하면
이런 방식으로 테이블이 생성된다. 이러한 경우를 막고 각자 테이블을 구현하기 위해서는
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Inheritance Joined 속성을 이용해서 만든다.
@DiscriminatorColumn
public class Items
@DiscriminatorColumn 을 사용하면 자동으로 DTYPE 을 생성해준다 -> select 쿼리문을 날리면 자동으로 MOVIE, BOOK , ALBUM 으로 구분된다. (싱글테이블 전략에서 필수)
@DiscriminatorValue("A")
public class Album extends Items
@DiscriminatorValue("name") 속성을 사용하면 DTYPE 에 들어가는 칼럼명이 A, M, B 등으로 변환 가능하다.
- 장점 : 테이블 정규화 , 외래 키 참조 무결성 제약조건 활용가능 ( 주문 테이블에서 아이템을 보고자 하는 경우 , ITEM을 조회해서 편하게 조회 가능) , 저장공간 효율화
- 단점 : 조회 시 , 조인을 많이 사용하여 성능 저하 , 조회 쿼리가 복잡합 , 데이터 저장시 INSERT 쿼리 2번 호출
※ 단일 테이블 전략
- 하나의 테이블에 모든 속성이 들어가 있는 전략
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
SINGLE_TABLE 로 바꿔주면 단일 테이블 전략으로 바뀌게 된다.
- 한줄에 모든 값이 다 들어가 있음.
- 장점 : 성능이 좋다. 조회 쿼리가 단순하다.(조인이 없으므로)
- 단점 : 자식 칼럼들은 모두 null 허용, 단일 테이블에 모두 저장하므로 테이블이 커질 수 있고 , 조회 성능이 오히려 느려질 수 있다.
-> 성능이 안나와서 테이블 전략을 바꾸더라도 @Inheritance 에서 strategy 만 바꿔주면 다른 변경 없이 전환이 가능! JPA의 장점
※ 구현 클래스마다 테이블 전략
- ITEM의 공통적인 부모 없이 전부 값을 상속받아서 테이블을 만든다.
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
- ITEM 테이블이 만들어지지 않고 자식 클래스들만 생성된다.
- DTYPE 이 생성되지 않으므로 ITEM 을 조회하는 쿼리를 날릴 때 , 모든 테이블이 select + union
돼서 모든 정보가 넘어온다.
--- 구현 클래스마다 테이블 전략은 사용 X ---
@MappedSuperclass
개발 도중 , 모든 항목에 작성자 , 작성일시 , 마지막 작성자 , 마지막 수정날짜 등의 정보를 넣고 싶다고 하는 경우
private String createdBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
다음과 같은 모든 코드를 전부 복사, 붙여넣기로 넣어줘야 한다.
이러한 경우 속성만 상속받는다면 훨씬 더 편하고 이를 위해서 @MappedSuperclass 사용 -> 매핑 정보만 받는 슈퍼클래스라고 이해하자
@MappedSuperclass
public class BaseEntity{
private String createdBy;
private LocalDateTime createdDate;
private String lastModifiedBy;
private LocalDateTime lastModifiedDate;
공통된 속성을 BaseEntity 에 만들고 , 상속하고자 하는 곳에 extends 로 상속한다.
@Entity
public class Members extends BaseEntity{
즉 , 공통된 속성을 같이 쓰기 위해서 사용한다.
BaseEntity 라는 엔티티 생성되지 않는다. / 속성만 내려주는 역할 -> 조회 , 검색이 불가
추상클래스로 사용한다.
public abstract class BaseEntity{
extends 를 사용하는 경우는 @Entity (상속관계) 이거나 , @MappedSuperclass (속성만 상속받을 때) 인 경우 사용한다.
* 해당 글은 'Infleran'의 김영한 강사님의 자료를 참조하였습니다.
'JPA Basic' 카테고리의 다른 글
변경 감지(Dirty Checking) & 병합(Merge) (1) | 2022.03.21 |
---|---|
JPA Basic - 6 (0) | 2021.12.30 |
JPA Basic - 4 (0) | 2021.12.28 |
JPA Basic - 3 (0) | 2021.11.18 |
JPA Basic - 2 (0) | 2021.11.16 |
댓글