[ 김영한 자바 ORM 표준 JPA 프로그래밍 - 기본편 #4 ] 매핑

김수호·2024년 5월 3일
0
post-thumbnail

👉 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
        • @SequenceGenerator 필요
      • TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용
        • @TableGenerator 필요
      • 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군데.
    • 그러면 결국 둘중 테이블의 외래 키를 관리할 곳을 지정해야 함.
      • 연관관계의 주인: 외래 키를 관리하는 참조
      • 주인의 반대편: 외래 키에 영향을 주지 않음, 단순 조회만 가능

강의를 듣고 정리한 글입니다. 코드와 그림 등의 출처는 김영한 강사님께 있습니다.

profile
현실에서 한 발자국

0개의 댓글