[JPA] Entity 매핑 - 필드와 컬럼 매핑

PURPLE·2022년 3월 22일
2

JPA

목록 보기
7/8


JPA를 사용하는 데 가장 중요한 일은 엔티티와 테이블을 정확히 매핑하는 것이다.
그러려면 JPA의 매핑 어노테이션을 잘 사용해야한다.
JPA가 지원하는 어노테이션은 크게 4가지로 분류할 수 있다.


annotation매핑 대상
@Column컬럼
@Enumerated자바의 enum 타입
@Termporal날짜 타입
@LobBLOB, CLOB
@Transient매핑 하지 않음

@Column

@Column 은 객체 필드를 테이블 컬럼에 매핑한다.
@Column 은 가장 많은 기능을 갖고 있는데, 다양한 속성들을 살펴보자.
(거의 사용하지 않는 속성은 제외하였다.)

속성명기능Default
name필드와 매핑할 테이블의 컬럼명객체의 필드명
nullable
(DDL)
null 값 허용 여부 설정
false로 설정하면 DDL 생성 시 not null 제약조건이 붙는다.
true
unique
(DDL)
한 컬럼에 간단히 유니크 제약조건을 걸 때 사용한다.
하지만 생성되는 제약조건 이름이 알아보기 힘든 문자로
생성되기 때문에 🔗@Table의 uniqueConstraints 속성을 이용해 name까지 같이 지정하는 방식을 더 많이 쓴다.
columnDefinition
(DDL)
데이터베이스 컬럼 정보를 직접 매핑필드의 자바 타입과 방언 정보를 사용해 적절한 컬럼 타입 생성
length
(DDL)
문자 길이 제약조건
String 타입에만 사용
255
precision,scale
(DDL)
BigDecimal/BigInteger 타입에서 사용
precision은 소수점을 포함한 전체 자리수
scale은 소수점 자리수
precision=19, scale=2

👩🏻‍🏫 nullable Ex.

@Column(nullable = false)
private String data;

// 생성된 DDL
// data varchar(255) not null

👩🏻‍🏫 unique Ex.

@Column(unique = true)
private String username;

// 생성된 DDL
// alter table TableName
//		add constraint UK_Xxx unique (username)

👩🏻‍🏫 columnDefinition Ex.

@Column(columnDefinition = "varchar(100) default 'EMPTY'")
private String data;

// 생성된 DDL
// data varchar(100) default 'EMPTY'

👩🏻‍🏫 length Ex.

@Column(length = 400)
private String data;

// 생성된 DDL
// data varchar(400)

👩🏻‍🏫 percision, scale Ex.

@Column(precision =10, scale = 2)
private BigDecimal cal;

// 생성된 DDL
// cal numeric(10,2)	H2, PostgreSQL
// cal number(10,2)		Oracle
// cal decimal(10,2)	MySQL

🚨 자바 데이터 타입(Primitive type)@Column
@Column 은 기본적으로 nullable이다.
때문에 null 값을 허용하지 않는 자바 데이터 타입 의 경우 @Column (nullable = false) 로 지정해야 안전하다. 만약, Integer 와 같은 객체 타입(Reference Type)이라면 @Column 을 생략해도 무방하다.

@Enumerated

자바의 enum 타입을 매핑할 때 유용하게 사용된다.

속성명기능Default
value- EnumType.ORDINAL : enum 순서를 저장
- EnumType.STRING : enum 이름을 저장
EnumType.ORDINAL

@Enumerated 를 사용할 때는 기본값인 EnumType.ORDINAL 보다는
EnumType.STRING 을 사용하는 것이 안전하다.
💡 왜냐하면, enum 클래스 내부에 정의된 순서가 항상 같을 것이라는 보장이 없기 때문이다. enum의 추가나 삭제 등으로 순서가 바뀌게 된다면, 데이터베이스 무결성을 해칠 수 있다.

다음과 같은 enum 클래스가 있을 경우

enum RoleType {
	ADMIN, USER
}

Entity에는 이렇게 매핑을 한다.

@Enumerated(EnumType.STRING)
private RoleType roleType;

코드를 작성할 때, 아래처럼 사용하면 된다.

memebr.setRoleType(RoleType.ADMIN); // -> 테이블의 role_type 컬럼에 'ADMIN'으로 저장된다.

만약, EnumType.ORDINAL 로 매핑을 했을 경우엔
데이터베이스에는 ADMIN 이 아닌 0 값이 저장된다.

@Temporal

날짜 타입을 매핑할 때 사용한다. (java.util.Date, java.util.Calendar)
하지만 Java8 이상 부터 사용 가능한 LocalDate, LocalDateTime 타입을 사용하면 생략 가능하다.

속성명매핑대상Default
value- TemporalType.DATE : 데이터베이스 date 타입
- TemporalType.TIME : 데이터베이스 time 타입
- TemporalType.TIMESTAMP : 데이터베이스 timestamp 타입
최신 Hibernate에선 생략해도 된다.
(Java8 이상)
@Temporal(TemporalType.DATE)
private Date date; //날짜

@Temporal(TemporalType.TIME)
private Date time; //시간

@Temporal(TemporalType.TIMESTAMP)
private Date timestamp; //날짜와 시간

@Lob

데이터베이스 BLOB, CLOB 타입과 매핑한다.
@LOB 은 지정할 수 있는 속성이 없다.
매핑하는 필드 타입이 문자면 CLOB 으로 매핑하고, 나머지는 BLOB 으로 매핑한다.

@Transient

@Transient 를 붙이면 해당 필드는 매핑하지 않는다.
데이터베이스에 저장하지 않고, 조회하지도 않기 때문에 객체에 임시로 값을 보관하고 싶을 때 사용한다.


참고

강의_자바 ORM 표준 JPA 프로그래밍 - 기본편
교재_자바 ORM 표준 JPA 프로그래밍(김영한)

다정한 피드백 환영해요 🤗

profile
방향과 방법을 찾아가는 여정

0개의 댓글