"인프런 - 자바 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 |