Back-End/JPA(자바 ORM 표준 기술)

[JPA][엔티티 매핑] - 엔티티 매핑

얄루몬 2022. 6. 2. 18:48

📖본 포스팅은 '자바 표준 ORM 기술 JPA - 김영한'님의 책을 보고 작성되었습니다.

1. @Entity

2. @Table

3. 다양한 매핑 사용

4. 데이터베이스 스키마 자동 생성

5. DDL 생성 기능

6. 기본 키 매핑

7. 필드와 컬럼 매핑: 레퍼런스


@Entity

JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션을 필수로 붙어야 한다. @Entity가 붙은 클래스의 경우엔 JPA가 관리하는 것으로, 엔티티라고 부른다.

@Entity 적용 시 주의사항

  • 기본 생성자는 필수다.
    • 파라미터가 없는 public 또는 protect 생성자
    • 엔티티 객체를 생성할 때 기본 생성자를 사용해서 JPA는 생성하기에 이 생성자는 반드시 있어야 한다.
    • 없다면 기본 생성자를 자동으로 만들어 준다. (생성자를 하나 이상 만들면 자바는 기본 생성자를 만들어주지 않기에 직접 만들어 해결해야 한다.)
  • final 클래스, enum, interface, inner 클래스에서는 사용할 수 없다.
  • 저장할 필드에 final을 사용하면 안 된다.

@Table

@Table은 엔티티와 매핑할 테이블을 지정해주는 애노테이션이다. 생략하게 되면 매핑한 엔티티 이름을 테이블 이름으로 사용한다.

다양한 매핑 사용

package jpabook.jpashop.domain.member;

import javax.persistence.*;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.Date;

@Entity
@Getter
@Setter
@Table(name = "MEMBER")
public class Member {

    @Id
    @Column(name = "ID")
    private String id;

    @Column(name="NAME")
    private String username;

    private Integer age;

    // == 추가 ==
    //1
    @Enumerated(EnumType.STRING)
    private RoleType roleType;

    //2
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate;
    
    //2
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;
    
    //3
    @Lob
    private String description;
}
  1. @Enumerated 
    • 자바의 enum을 사용해서 회원 타입을 구분해주었다.
    • 일반 회원은 USER, 관리자는 ADMIN이다.
    • 자바의 enum을 사용하려면 @Enumerated 애노테이션으로 매핑해주어야 한다.
  2. @Tempral
    • 자바의 날짜 타입을 매핑할 때 사용한다.
  3. @Lob
    1. CLOB, BLOB 타입을 매핑할 수 있다.(https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=rlasksdud53&logNo=220595010315)

roleType enum 클래스

package jpabook.jpashop.domain.member;

public enum RoleType {
    ADMIN, USER
}

데이터베이스 스키마 자동 생성

JPA는 데이터베이스 스키마를 자동으로 생성하는 기능을 지원한다. JPA는 클래스 매핑 정보와 데이터베이스 방언을 사용해 데이터베이스 스키마를 생성해준다.

JPA 2.1부터 스키마 자동 생성 기능을 표준으로 지원한다. 

DDL 생성 기능

제약 조건이 추가 될때 스키마 자동 생성하기를 통해 만들어지는 DDL에 이 제약 조건을 추가해보자. (제약 조건: 회원 이름은 필수로 입력되어야 하고 10자를 초과하면 안 된다.)

제약 조건 추가

@Column(name="NAME", nullable = false, length = 10) //제약조건 추가
private String username;
  • 이렇게 엔티티에 추가해주면 DDL에 우리의 제약조건을 매핑정보를 그대로 넣어준다.

생성된 DDL

유니크 제약조건

@Table(name = "MEMBER", uniqueConstraints = {@UniqueConstraint(
        name = "NAME_AGE_UNIQUE",
        columnNames = {"NAME", "AGE"})})

유니크 제약 조건 설정

  • UniqueConstraint는 유니크 제약 조건을 만들어준다.
  • 이런 기능은 DDL을 자동 생성할 때만 사용하고 JPA 실행 로직에는 영향을 주지 않는다.

기본 키 매핑

@Id를 사용해서 우리가 직접 기본키를 지정해주는 방법 말고 데이터베이스가 제공하는 기본키를 사용하려면 어떻게 매핑해야 할지 다음을 통해 살펴보도록 하자

JPA가 제공하는 데이터베이스 기본 키 생성 전략

  1. 직접 할당: 기본키를 애플리케이션에서 직접 할당한다.
    • @Id 애노테이션을 사용해서 직접 기본키로 할당해준다.
    • 자바 기본형, 자바 래퍼형, String, java.utill.Date, java.sql.Date, java.math.BigDecimal, java.math.BigInteger 에서만 직접 할당이 가능하다.
    • em.persist( )로 엔티티 저장 전 애플리케이션에서 기본키를 직접 할당하는 방식이다.
  2. 자동 생성: 대리 키 사용 방식
    • IDENTITY: 기본 키 생성을 데이터베이스에 위임한다.
      • 데이터베이스에 의존한다.
    • SEQUENCE: 데이터베이스 시퀀스를 사용해 기본 키를 할당한다.
      • MySQL은 이를 지원하지 않는다.(대신 AUTO_INCREMENT를 제공)
      • 데이터베이스에 의존한다.
    • TABLE: 키 생성 테이블을 사용한다.

 

필드와 컬럼 매핑: 레퍼런스

JPA가 제공하는 필드와 컬럼 매핑용 애너테이션들을 레퍼런스 형식으로 정리

@Column

  • 컬럼을 매핑한다.
    • 속성
      • name
        • 필드와 매핑할 테이블의 컬럼 이름
        • 기본값은 필드의 이름
      • insertable
        • 필드의 저장 가능 여부
        • false일 시 읽기 전용
        • 기본값 true
      • updatable
        • 필드의 수정 가능 여부
        • false일 시 읽기 전용
        • 기본값 true
      • table
        • 속성이 매핑될 테이블 이름
        • 하나의 테이블을 두 개 이상의 테이블에 매핑할 때 사용
        • 기본값은 현재 클래스가 매핑된 테이블
      • nullable(DDL)
        • null 값 허용 여부
        • 기본값 true
      • unique(DDL)
        • 유니크 제약조건 여부
        • @uniqueConstraints와 같지만 한 컬럼에 간단히 걸 때 사용한다.
      • columnDefinition(DDL)
        • 컬럼의 타입을 직접 지정할 수 있다.
      • length(DDL)
        • 문자열의 길이 제약 조건, String에만 사용 가능하다.
        • 기본값 255
      • precision, scale(DDL)
      • BigDecimal 타입에서 사용
      • precision은 소수점을 포함한 전체 자릿수(유효숫자)를 의미한다.
      • scale은 소수의 자릿수를 의미한다.

@Enumerated

  • enum 타입을 매핑할 때 사용한다.
  • 종류
    • EnumType.ORDINAL
      • enum의 값을 DB에 저장한다.
      • enum이 변경될 경우에도 DB는 변경되지 않기 때문에 추천되지 않는다.
    • EnumType.STRING
      • enum의 이름을 문자열로 DB에 저장한다.

@Temporal

  • 날짜 타입을 매핑할 때 사용한다.
  • 생략할 경우 timestamp와 매핑된다.
  • 종류
    • TemporalType.DATE
      • DB의 date(연월일) 타입과 매핑
    • TemporalType.TIME
      • DB의 time(시분초) 타입과 매핑
    • TemporalType.TIMESTAMP
      • DB의 timestamp(date + time) 타입과 매핑
      • DB에 따라 datetime과 매핑

@Lob

  • 길이 제한이 없는 큰 데이터와 매핑된다.
  • 문자를 수식하면 CLOB, 이외에는 BLOB으로 매핑된다.

@Transient

  • 매핑하지 않을 필드를 수식한다.

@Access

  • JPA가 엔티티 데이터에 접근하는 방식을 지정한다.
    • AccessType.FIELD
      • 필드에 직접 접근한다. private이어도 접근 가능하다.
    • AccessType.PROPERTY
      • Getter를 사용해 접근한다.