👉 JPA 매핑은 크게 아래 4가지로 분류할 수 있다.
- 객체와 테이블 매핑 (
@Entity
, @Table
)
- 필드와 컬럼 매핑 (
@Column
, @Temporal
, @Enumerated
, @Lob
, @Transient
)
- 기본 키 매핑 (
@Id
, @GeneratedValue
)
- 연관관계 매핑 (
@ManyToOne
, @OneToMany
, @OneToOne
, @ManyToMany
, @JoinColumn
)
✔️ 객체와 테이블 매핑
@Entity
@Entity
가 붙은 클래스는 JPA가 관리하며, 엔티티라 한다. ( @Entity
가 붙지 않으면 JPA 와 전혀 관계없는 클래스이다. )
- JPA 를 사용해서 테이블과 매핑할 클래스는
@Entity
를 필수로 적용해야 한다.
- 주의)
- 기본 생성자를 필수로 작성해 주어야 한다.
- 파라미터가 없는 public 또는 protected 생성자
- final 클래스, enum, interface, inner 클래스 사용 X
- DB에 저장하고자 하는 필드에 final 사용 X
- 속성) name
- JPA에서 사용할 엔티티 이름을 지정한다.
- 기본값: 클래스 이름을 그대로 사용 (ex. Member)
- 같은 클래스 이름이 없다면 가급적 기본값을 사용한다.
@Table
- @Table 은 엔티티와 매핑할 테이블 지정
- 속성) name
- 매핑할 테이블 이름 ( 기본값: 엔티티 이름을 사용 )
✔️ 필드와 컬럼 매핑
@Column
: 컬럼 매핑
@Temporal
: 날짜 타입 매핑
@Enumerated
: enum 타입 매핑
@Lob
: BLOB, CLOB 매핑
@Transient
: 특정 필드를 컬럼에 매핑하지 않음 (필드 매핑 무시)
✔️ 기본 키 매핑
- 직접 할당:
@Id
만 사용
- 자동 생성:
@GeneratedValue
사용
- 전략 (strategy)
IDENTITY
: 데이터베이스에 위임, MYSQL
SEQUENCE
: 데이터베이스 스퀀스 오브젝트 사용, ORACLE
TABLE
: 키 생성용 테이블 사용, 모든 DB에서 사용
AUTO
: 방언에 따라 자동 지정, 기본값
✔️ 연관관계 매핑
- 다중성
@ManyToOne
, @OneToMany
, @OneToOne
, @ManyToMany
, @JoinColumn
- 단방향 연관관계
- 양방향 연관관계
- 매핑 규칙
객체의 두 관계중 하나를 연관관계의 주인으로 지정
- 주인을 무엇으로 정할 것인지에 대한 판단 기준은, 외래키를 어느쪽에서 가지고 있는지를 기준으로 결정하자. (외래키가 있는 곳이 연관관계의 주인)
연관관계의 주인만이 외래 키를 관리 (등록, 수정)
주인이 아닌쪽은 읽기만 가능
주인은 mappedBy 속성 사용 X
- 참고) mappedBy 속성: 양방향 연관관계를 맺을때 관계의 주인을 설정
주인이 아니면 mappedBy 속성으로 주인 지정
- 주의)
- 순수 객체 상태를 고려해서 항상 양쪽에 값을 설정하자.
- 연관관계 편의 메소드를 생성하자.
- 양방향 매핑시에 무한 루프를 조심하자. (ex. toString(), lombok, JSON 생성 라이브러리)
- 참고) 컨트롤러에서 API 응답 시 엔티티를 반환하지 말자. (DTO 로 변환해서 반환하자.) 엔티티를 직접 반환하게 되면, 엔티티 변경시 API 스펙이 바뀌어 버리는 이슈가 있을 수도 있다.
- 참고)
- 연관 관계 매핑에서 가장 중요한 것은, 먼저 단방향 연관관계를 매핑하는것이다. ( 양방향 매핑은 반대쪽에서 조회 기능만 추가된 것 )
✔️ 참고) 연관관계 매핑시 고려사항 3가지
다중성
다대일 [N:1]
: @ManyToOne
일대다 [1:N]
: @OneToMany
- 1이 연관관계 주인에 해당하는 경우
- 참고로 이런 유형은 실무에서 권장하지 않는다.
- 실무에서는 다대일 단방향 관계 + 필요시 양방향을 추가하는 전략으로 한다.
일대일 [1:1]
: @OneToOne
- 일대일 관계는 그 반대도 일대일
- 주 테이블이나 대상 테이블 중에 외래 키 선택 가능
- 주 테이블에 외래 키
- 주 객체가 대상 객체의 참조를 가지는 것 처럼, 주 테이블에 외래 키를 두고 대상 테이블을 찾음
- 객체지향 개발자 선호
- JPA 매핑 편리
- 장점: 주 테이블만 조회해도 대상 테이블에 데이터가 있는지 확인가능
- 단점: 값이 없으면 외래 키에 null 허용
- 대상 테이블에 외래 키
- 대상 테이블에 외래 키가 존재
- 전통적인 데이터베이스 개발자 선호
- 장점: 주 테이블과 대상 테이블을 일대일에서 일대다 관계로 변경할 때 테이블 구조 유지
- 단점: 프록시 기능의 한계로 지연 로딩으로 설정해도 항상 즉시 로딩됨 (프록시는 이후 설명)
- 외래 키에 데이터베이스 유니크(UNI) 제약조건 추가
다대다 [N:M]
: @ManyToMany
- 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없음
- 연결 테이블을 추가해서 일대다, 다대일 관계로 풀어내야 함
- 테이블의 N:M 관계는 중간 테이블을 이용해서 1:N, N:1
- 참고) 다대다 관계는 실무에서 사용하지 X
단방향, 양방향
- 테이블
- 테이블은 외래 키 하나로 양쪽으로 조인할 수 있다.
- 따라서 사실 방향이라는 개념이 없다.
- 객체
- 참조용 필드가 있는 쪽으로만 참조 가능
- 한쪽만 참조하면 단방향
- 양쪽이 서로 참조하면 양방향(=양쪽을 서로 참조하도록 개발할 때)
- 참고로 양방향이라는 말은 사실 단방향이 2개 있는것이다.
양방향일 때, 연관관계의 주인
- 객체 양방향 관계의 경우, A -> B, B -> A 처럼 참조가 2군데.
- 그러면 결국 둘중 테이블의 외래 키를 관리할 곳을 지정해야 함.
- 연관관계의 주인: 외래 키를 관리하는 참조
- 주인의 반대편: 외래 키에 영향을 주지 않음, 단순 조회만 가능
강의를 듣고 정리한 글입니다. 코드와 그림 등의 출처는 김영한 강사님께 있습니다.