프레임워크(Framework)/JPA

[JPA] 필드와 컬럼 간의 매핑 - 엔티티 매핑(Entity Mapping) - 3

잇트루 2022. 12. 1. 01:10
반응형
본 내용은 온라인 강의 사이트 인프런의 김영한 님의 강의 내용이 포함되어 있습니다.
'자바 ORM 표준 JPA 프로그래밍 - 기본편'
 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., - 강의 소개 | 인프런

www.inflearn.com

 

Intro

엔티티 매핑과 연관관계 매핑

JPA를 이용해 데이터베이스의 테이블과 상호 작용(데이터 저장, 수정, 조회, 삭제 등) 하기 위해 먼저 해야 하는 작업은 데이터베이스 테이블과 엔티티 클래스 간의 매핑 작업이다.

 

엔티티 매핑 작업은 객체와 테이블 간의 매핑, 기본키 매핑, 필드와 컬럼 간의 매핑, 엔티티 간의 연관 관계 매핑 등으로 나눌 수 있다.

 

특히 엔티티 간의 연관 관계 매핑은 JPA에서 가장 어려우면서도 중요하다.

 

엔티티 매핑

  • 객체와 테이블 간의 매핑 : @Entity, @Table
  • 필드와 컬럼 간의 매핑 : @Column
  • 기본 키 매핑 : @Id
  • 연관관계 매핑 : @ManyToOne, @JoinColumn, @OneToMany, @ManyToMany

 

 

필드와 컬럼 간의 매핑 - @Column, @Temporal, @Enumerated, @Lob, @Transient

필드와 컬럼 간의 매핑 어노테이션의 종류

@Column : 컬럼 매핑

@Temporal : 날짜 타입 매핑

@Enumerated : enum 타입 매핑

@Lob : BLOB, CLOB 매핑

@transient : 특정 필드를 컬럼에 매핑하지 않음(매핑 무시)

@Entity
@Table
public class Member {

    @Id
    private Long id;

    @Column(name = "name") // 데이터베이스 컬럼 명은 name
    private String username; // 객체는 username

    private Integer age;

    @Enumerated(EnumType.STRING)
    private RoleType roleType;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;

    @Lob
    private String description;

    @Transient // 데이터베이스 컬럼에 매핑되지 않음
    private int temp;

    public Member() {
    }

    // Getter
    // ...
    // Setter
    // ...
    }
}

 

@Column

@Column 어노테이션을 통해 필드와 컬럼을 매핑할 수 있다.

만약, @Column 어노테이션이 없고 필드만 정의되어 있다면, JPA는 기본적으로 해당 필드가 테이블의 컬럼과 매핑되는 필드라고 간주하게 된다.

또한, @Column 어노테이션에서 사용되는 속성들을 모두 기본 값으로 적용된다.

@Column(name = "name") // 데이터베이스 컬럼 명은 name
private String username; // 객체는 username

속성

  • name
    • 필드와 매핑할 테이블의 컬럼 이름을 지정한다.
    • 기본 값은 객체 필드 이름을 그대로 사용한다.
  • nullable
    • 컬럼에 null 값을 허용할지 여부를 지정한다.
    • 기본 값은 true로 null 값을 허용한다.(false시 not null)
    • 회원의 이메일, 전화번호 등은 필수적으로 입력해야 한다면, 많아 false로 지정하여 사용할 수 있다.
  • updatable, insertable
    • 컬럼 데이터를 수정 및 변경을 할 수 있는지의 여부를 지정한다.
    • 기본 값은 true로 수정을 허용한다.
  • unique
    • 하나의 컬럼에 unique 제약 조건을 설정한다.
    • 기본 값은 false로 고유하지 않아도 되는 것을 의미한다.
    • email, 전화번호 등을 고유하도록 설정해야 한다면, unique 값을 true로 지정하여 사용할 수 있다.
  • columnDefinition
    • 데이터베이스 컬럼 정보를 직접 줄 수 있다.
    • ex) varchar(100) default ‘EMPTY’
  • length
    • 문자 길이 제약조건을 설정할 수 있다.
    • 기본 값은 255이다.
    • 단, String 타입에만 사용한다.
  • precision, scale
    • BigDecima 타입에서 사용하는 아주 큰 숫자나 정밀한 소수를 다룰 때 사용한다.
    • precision : 소수점을 포함한 전체 자릿수(기본값 = 19)
    • scale : 소수의 자릿수(기본값 = 2)
    • BigInteger에서도 사용이 가능하다.

 

 

@Column 어노테이션을 사용하지 않거나, 기본값을 사용할 경우 주의 사항

@Column은 기본적으로 nullable=true 이다.

만약, 필드의 데이터 타입이 int, long과 같은 자바의 원시 타입이라면, null 값을 허용하지 않는 속성이 있다.

따라서, nullable이 true여도 null이 저장되지 않는다.

 

 

@Enumerated

자바의 enum 타입을 매핑할 때 사용하는 어노테이션이다.

@Enumerated(EnumType.STRING)
private RoleType roleType;

속성

  • value
    • EnumType.ORDINAL : enum 순서를 데이터베이스에 저장(0, 1, 2, …)
    • EnumType.STRING : enum 이름을 데이터베이스에 저장(ONE, TWO, THREE, …)
    • 기본 값은 EnumType.ORDINAL이다.

 

 

주의 사항

기본 값은 EnumType.ORDINAL이지만 사용하면 안 된다.

다음과 같이 enum 타입이 존재한다고 가정한다.

public enum RoleType {
    USER, ADMIN
}

만약 EnumType.ORDINAL일 경우, USER는 0, ADMIN은 1이라는 Integer 타입의 값이 데이터베이스에 저장될 것이다.

 

이후 요구 사항이 변경되어 GUEST라는 Enum타입이 추가되어 코드를 다음과 같이 수정한다.

public enum RoleType {
    GUEST, USER, ADMIN
}

이 경우, ORDINAL은 순서를 저장하기 때문에, GUEST는 0, USER는 1, ADMIN은 2라는 값으로 저장되게 된다.

하지만, enum 클래스가 수정되기 이전에 USER, ADMIN에는 0, 1이라고 저장되어 있던 값이 변경되지 않는다.

이는 데이터에 치명적인 문제가 생기게 된다.

 

enum 타입을 매핑할 경우 EnumType.String을 사용해야 한다

 

 

@Temporal

날짜 타입(java.util.Date, java.util.Calender)을 매핑할 때 사용하는 어노테이션이다.

@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;

@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;

속성

  • value
    • TemporalType.DATE : 날짜, 데이터베이스 date 타입과 매핑(2022-11-16)
    • TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑(12:30:57)
    • TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑(2022-11-16 12:30:57)

 

 

참고로 LocalDate, LocalDateTime을 사용할 경우 생략이 가능하다.

따라서, 최근에는 많이 사용하지 않는 어노테이션이다.

private LocalDate localDate;
private LocalDateTime localDateTime;

 

 

@Lob

데이터베이스의 BLOB, CLOB 타입과 매핑할 때 사용한다.

매핑하는 필드 타입이 문자면 CLOB, 나머지는 BLOB을 매핑한다.

  • CLOB : String, char[], java.sql.CLOB
  • BLOB: Byte[], java.sql.BLOB
@Lob
private String description;

@Lob은 별도로 지정할 수 있는 속성이 없다.

 

 

@Transient

@Transient 어노테이션을 지정한 필드는 데이터베이스의 컬럼에 매핑되지 않는다.

따라서, 데이터베이스에 저장이 되지 않는다.

주로 메모리상에서만 사용하거나 보관할 때 사용한다.

@Transient // 데이터베이스 컬럼에 매핑되지 않음
private int temp;
반응형