본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
JPA

필드와 컬럼 매핑 - 1

by 방구석 대학생 2020. 9. 19.

"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."

www.inflearn.com/course/ORM-JPA-Basic#

 

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

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

www.inflearn.com

 

- 필드와 컬럼 매핑은 다양한 케이스가 가능하다.

다음과 같은 요구사항을 프로젝트에 추가해보자.

1. 회원은 일반 회원과 관리자로 구분해야 한다.

2. 회원 가입일과 수정일이 있어야 한다.

3. 회원을 설명할 수 있는 필드가 있어야 한다.(이 필드는 길이 제한이 없다.)

 

Member 도메인 클래스

import javax.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;

@Entity
public class Member {
	
    	@Id
        private Long id;
        
        @Column(name = "name")
        private String 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;
        
        // Getter, Setter
}

 

@Enumerated 어노테이션

- enum 타입의 필드를 쓰고 싶은데 데이터베이스 에는 enum 타입이 존재하지 않는다, 이때 @Enumerated 어노테이션을 활용하면 된다.

- 여기서 enum 타입이란 한정된 데이터들을 갖는 데이터를 열거형으로 한번에 묶어주는 타입이다.(대표적으로 "요일" 이나 "계절" 이 있다.)

 

public enum RoleType {
	USER, ADMIN
}

 

* enum 타입을 쓸 때 주의사항

: EnumType 은 두 가지 속성을 선택할 수 있다.

ORDINARY - enum 의 순서를 데이터베이스에 저장한다.(기본 default 값)

  -> integer 타입으로 컬럼을 생성해준다.(데이터가 숫자로 들어가기 때문)

  -> 데이터 삽입 후 실행한 다음 H2 console 의 데이터베이스 테이블을 보면 ROLETYPE 컬럼에 0 이라는 값이 들어가있다.(0 부터 시작하여 이후에 들어오는 값들은 1씩 값이 증가한다.)

 

그런데 기본값인 ORDINARY 는 사용하면 안된다. 왜?

 

먄약 중간에 요구사항이 변경되어서 enum 타입에 들어있는 데이터들의 순서가 변경된다면 어떤일이 벌어질까?

이미 ROLETYPE 값으로 0 을 가지는 데이터가 있는데 또 다시 0 값을 가지는 데이터가 삽입되는 경우가 발생할 수 있다.

(운영상 굉장히 위험해진다.)

그래서 꼭 필수로 STRING 으로 타입을 지정해주자.

 

- EnumType.ORDINAL : enum 순서를 데이터베이스에 저장한다.

- EnumType.STRING : enum 이름을 데이터베이스에 저장한다.(되도록이면 데이터를 String 형식의 이름으로 지정해주자.)

 

 

@Temporal 어노테이션

날짜(Date, Calendar) 타입을 매핑할 경우 사용할 수 있는 어노테이션

타입이 3가지가 존재한다.

- TemporalType.DATE : 날짜, 데이터베이스 date 타입과 매핑(2020-09-19)

- TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑(22 : 01 : 04)

- TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑(2020-09-19 22 : 01 : 04)

 

자바의 Date 타입 안에는 날짜와 시간이 모두 존재하지만 데이터베이스는 보통 이 정보들을 구분해서 사용하기 때문에 타입에 관하여 어노테이션을 통해 매핑을 해주어야 한다.

-> 그런데 옛날에 쓰던 코드의 경우에는 필요하겠지만 지금은 필요하지 않다!!

 

지금은 자바8 을 활용하게 되면서 LocalDate, LocalDateTime 을 사용하게 되었다.(최신 hibernate 를 지원한다.)

hibernate 최신버전을 사용한다면 그냥 위의 두 타입을 사용하면 된다.(굳이 @Temporal 어노테이션을 사용할 필요가 없다.)

- LocalDate : 연, 월만 포함되어 있는 데이터

- LocalDateTime : 연, 월, 일 모두 포함되어 있는 데이터

 

@Entity
public class Member{
	.......
    private LocalDate testLocalDate;
    private LocalDateTime testLocalDateTime;
}

 

위와 같이 도메인 클래스를 구성 하였을 경우 hibernate message

Hibernate: 
    
    create table Member (
       id bigint not null,
        roleType varchar(255),
        testLocalDate date,
        testLocalDateTime timestamp,
        name varchar(255) not null,
        primary key (id)
    )

 

 

@Lob 어노테이션

: 데이터베이스에 크기가 큰 컨텐츠를 넣고 싶을 경우 사용하는 어노테이션(데이터베이스 BLOB, CLOB 과 매핑된다.)

- @Lob 어노테이션은 지정할 수 있는 속성이 없다.

- 매핑하는 필드 타입이 문자면 CLOB, 나머지는 BLOB 으로 매핑된다.

CLOB : String, char[], java.sql.CLOB

BLOB : byte[], java.sql.BLOB

 

 

@Transient 어노테이션

- DB 와 전혀 상관없이 메모리 상에서만 사용하고 싶은 경우 붙이는 어노테이션 이다.

- 필드 매핑, 데이터베이스 저장, 조회 등을 일체 지원하지 않는다.

- 주로 메모리 상에서만 임시로 어떤 값을 보관하고 싶을 때 사용한다. 

 

- hibernate message

아래의 메세지를 보면 @Lob 어노테이션 으로 매핑된 description 변수가 clob 으로 매핑되어 있는 것을 알수 있다.

Hibernate: 
    
    create table Member (
       id bigint not null,
        description clob,
        roleType varchar(255),
        testLocalDate date,
        testLocalDateTime timestamp,
        name varchar(255) not null,
        primary key (id)
    )

 

또한 아래와 같이 @Transient 어노테이션으로 매핑된 변수는 테이블에 컬럼으로 생성되지 않았음을 알 수 있다.

@Transient
private Integer temp;

'JPA' 카테고리의 다른 글

기본 키 매핑 - 1  (0) 2020.09.21
필드와 컬럼 매핑 - 2  (0) 2020.09.19
객체와 테이블 간 Entity 매핑  (0) 2020.09.19
준영속 상태에 대하여....  (0) 2020.09.12
플러시(flush) 에 대하여...  (0) 2020.09.11