Back-end/JPA 개념

5. Field(칼럼) Mapping

devraphy 2022. 3. 28. 20:06

0. 개요

- 이전 포스팅에서 Entitty와 DB Table을 매핑하는 방법에 대해서 알아보았다.

- 이번 포스팅에서는 Field와 DB Column을 매핑하는 방법에 대해서 알아보자.

 

1.  Annotation

- Field Mapping에 사용되는 기본적인 Annotation에 대해서 알아보자.

 

a) @Column

- DB 테이블의 Column을 Entity 필드로 매핑할 때 사용한다.

- Enitity 변수와 Column의 이름이 다르다면, @Column의 name 속성을 이용하여 DB의 Column을 명시한다.

@Entity
public class User {
   
   @Column(name = "fullName")
   private string userName;
   
}

 

b) @Enumerated

- Entity에서 enum 타입의 필드를 매핑할 때 사용한다.

- DB에는 enum 타입이 존재하지 않지만, JPA가 이를 알아서 변환해준다.

- @Enumerated를 사용할 때에는 enum의 타입을 반드시 매개변수에 명시한다.

@Entity
public class User {
   
   @Enumerated(EnumType.STRING)
   private Role role;
   
}

- EnumType.ORDINAL은 @Enumerated의 기본 값으로, enum의 순서를 DB에 저장한다.

- EnumType.STRING은 enum의 이름을 DB에 저장한다.

 

* 주의하자!

- EnumType은 반드시 STRING으로 명시한다.

- ORDINAL을 사용하면 enum의 순서를 저장하므로, 운영 데이터의 무결성을 위배할 수 있다.

 

c) @Temporal

- Entity에서 날짜 타입의 필드를 매핑할 때 사용한다.

- java.util.Date 또는 java.util.Calendar를 자료형으로 선언하는 경우 사용하는 annotation이다.

- @Tempral을 사용할 때에는 반드시 매개변수에 타입을 명시한다.

@Entity
public class User {
   
   @Temporal(TemporalType.TIMESTAMP)
   private Date signUpDate;
   
}

 

* 주의하자!

- @Temporal은 현재 사용되지 않는 annotation이다.

- 자바 8부터 LocalDate와 LocalDateTime이 등장하면서, @Temporal은 생략이 가능해졌다.

 

- @Temporal을 사용하는 이유는 날짜 데이터의 형식을 설정하기 위해서다.

- LocalDate(= DATE)와 LocalDateTime(= TIMESTAMP)은 각각 다른 날짜 형식을 지원하며, 자료형으로 사용할 수 있다.  

- 그러므로 @Temporal은 더 이상 잘 사용하지 않는다.

 

d) @Lob

- Lob(= Large object)은 이름 그대로 대용량의 데이터를 보관하는 Column을 매핑할 때 사용한다.

- @Lob은 BLOB(= byte [], java.sql.BLOB)와 CLOB(= String, char [], java.sql.CLOB) 타입을 지원한다.

   → BLOB: 이미지, 음악파일, 비디오 등 DB에 존재하는 대용량 데이터

   → CLOB: DB에 존재하는 대용량 텍스트 

@Entity
public class User {
   
   @Lob
   private String desc;
   
}

- 위의 예시 코드에서 @Lob을 부여한 필드가 String 이므로 CLOB에 해당된다.

 

e) @Transient

- Entity의 필드로 존재하지만, Column과는 매핑되지 않는 필드인 경우 사용한다.

@Entity
public class User {
   
   @Transient
   private int temp;
   
}

 

2. @Column 옵션

a) name 옵션

- Entity 필드와 매핑할 DB 테이블의 칼럼 이름을 명시한다.

@Entity
public class User {
   
   @Column(name = "name")
   priavate String userName;
   
}

 

b) insertable, updatable 옵션

- 해당 칼럼의 내용을 새로 생성(= INSERT)하거나 변경(= UPDATE)의 가능 여부를 명시한다.

- DB에서 직접 SQL을 작성하여 INSERT 또는 UPDATE를 할 수 있지만, JPA에서는 설정에 따라 작동하게 된다.

@Entity
public class User {
   
   @Column(insertable = true, updatable = false)
   priavate String userName;
   
}

 

c) nullable 옵션 (DDL)

- 해당 column에서 null 값의 허용 여부를 명시한다.

- false로 설정하면 not null 제약조건이 붙은 column이 된다.

@Entity
public class User {
   
   @Column(nullable = false)
   priavate String userName;
   
}

 

d) unique 옵션 (DDL)

- @Table의 unique옵션(= uniqueConstraints)과 동일한 기능이지만, 특정 컬럼 하나에만 제약조건을 부여한다.

- 칼럼에 unique 제약조건을 부여하고 싶다면 true, 아니라면 false를 명시한다.

@Entity
public class User {
   
   @Column(unique = false)
   priavate String userName;
   
}

 

* 주의하자!

- 이 방식은 잘 사용하지 않는다.

- 왜냐면 부여되는 제약 조건의 이름이 복잡하기 때문이다.

- 아래의 사진처럼 이름의 가독성이 떨어지므로 어떤 제약인지 이해하기 어렵다.

 

- 그러므로 Column 단위로 제약조건을 걸기보다는 @Table을 사용한다.

- @Table의 uniqueConstraints 옵션을 이용하여 unique 제약조건의 이름을 직접 부여할 수 있다.

@Entity
@Table(uniqueConstraints = "이름 설정")
public class User {
}

 

e) columnDefinition 옵션 (DDL)

- DB 테이블의 column 정보를 직접 작성하는 경우 사용한다.

@Entity
public class User {
   
   @Column(columnDefinition = "varchar(50) default 'None'")
   priavate String userName;
   
}

 

f) precision, scale 옵션 (DDL)

- 필드의 자료형이 BigDecimal 또는 BigInteger일 때 사용할 수 있는 옵션이다.

- precision은 소수점을 포함한 전체 자릿수를 설정하는 옵션이다.

- scale은 소수의 자릿수를 설정하는 옵션이다.

- 정밀하게 소수를 다루거나 아주 큰 숫자를 다룰 때 사용한다.

@Entity
public class User {
   
   @Column(scale = 2,  precision = 10)
   private BigInteger age;
   
}