study/backend

[TIL] 13 엔티티 매핑

SHplusR 2023. 6. 26. 23:35

@Entity 

: jpa를 사용하여 테이블과 매핑할 클래스에 붙이는 어노테이션.

특이사항

1. 기본생성자가 필수다.

2. final class, enum, interface, inner class 에는 사용할 수 없다.

3. 저장할 필드에 final 을 사용하면 안 된다.

 

@Table

: 엔티티와 매핑할 테이블을 지정한다. 생략하게되면 엔티티 이름을 테이블 이름으로 사용한다.

 

ex)

@Entity
@Table(name="MEMBER")
public class Member {

 

DDL : 

Data Definition Language로, 데이터 베이스 스키마를 정의하는 일련의 sql 명령이다.

그 종류에는 

create, alter, drop, truncate 가 있다.

 

DDL 생성기능 :

 

@Column(name = "NAME", nullable = false, length = 10)
private String username;

 

column 어노테이션을 이용하여 제약조건 추가가 가능하다.

nullable에 false를 주었다는 것은, not null 제약조건을 추가한단뜻이고, 

length = 10은 문자의 크기를 10만큼 지정하겠단 뜻이다.

--> 이 기능들은 단지 DDL을 자동생성할때만 사용된고 실제 jpa의 실행로직에는 아무 영향을 주지 않는다!

 

나는 주로 기본키를 생성할때,

@GeneratedValue(strategy = GenerationType.IDENTITY)

위와 같은 IDENTITY 전략을 사용했다.

다른 의미는 없고, 처음으로 클론코딩한 코드에서 항상 기본키를 이렇게 설정했기 때문에 습관처럼하고 있었다.

 

IDENTITY 전략 

: 기본 키 생성을 db에 위임하는 전략이다.

db에 값을 저장하고 나서야 기본 키 값을 구할 수 있을 때 사용된다.

** 이 전략은 트랜잭션을 지원하는 쓰기 지연은 동작하지 않는다.

 

 

SEQUENCE 전략

: 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트이다.

먼저 시퀀스를 생성하고,  사용할 데이터 베이스 시퀀스를 매핑(및 생성), 그리고 이렇게 만든 시퀀스 생성기를 

GeneratedValue에 속성으로 넣어야한다.

IDENTITY SEQUENCE
em.persist()를 호출하는 즉시 insert sql문이 db에 전달된다.
(그래서 쓰기 지연이 동작 X)
해당 전략은 엔티티를 db에 저장해야 식별자를 구할 수 있다.
(엔티티가 영속상태가 되려면 꼭 식별자가 필요하다)
이후 식별자를 조회하여 엔티티를 해당 식별자에 할당한다.
em.persist()를 호출할 때 먼저 데이터베이스 시퀀스를 사용하여 식별자를 조회한다. 
그리고 조회한 식별자를 엔티티에 할당한 후에 엔티티를 영속성 컨텍스트에 저장한다. 
이후 트랜잭션을 커밋해서 플러시가 일어나면 엔티티를 db에 저장한다

 

TABLE 전략 :

키 생성 전용 테이블을 만들고 이름과 값으로 사용할 칼럼을 만든다 ( db 시퀀스를 따라한것)

이 전략은 테이블을 사용하므로 모든 db에 적용할 수 있다.

 

TABLE
데이터베이스 시퀀스 생성용 테이블에서 식별자 값을 획득한 후, 식별자를 엔티티에 할당한 후에 해당 엔티티를  영속성 컨텍스트에 저정한다.

 

 

AUTO 전략 :

데이터베이스 방언에 따라 위에 설명한 전략 중 하나를 자동으로 선택한다.

( @GeneratedValue.strategy의 기본값은 auto다.)

 

 

@Enumerated:

자바의 enum 타입을 매핑할 때 사용이 된다. 아래와 같이 사용한다.

 

Member.java (entity)

@Enumerated(EnumType.STRING)
private RoleType roleType;

 

RoleType.java

public enum RoleType {
    ADMIN, USER
}
EnumType.STRING EnumType.ORDINAL
enum 이름 그대로 ADMIN은 "ADMIN" USER는 "USER" 로 저장된다.
enum에 저장된 순서에 관계 없으며 다른 enum이 추가되어도 상관없다.
하지만 db에 저장되는 데이터 크기가 ordinal보다 크다.
enum에 저장된 순서대로 ADMIN은 0, USER는 1로 저장된다.
enum에 저장된 순서를 변경할 수 없다.
하지만 db에 저장되는 데이터 크기가 작다.
( 흠......나중에 고칠때 정말 안 좋다....)

 

@Temporal

: 날짜 타입을 매핑할 떄 사용한다. 

TemporalType에는 DATE(날짜, 데이터베이스 data타입과 매핑) , TIME(시간, 데이터베이스 tim타입과 매핑),

TIMESTAMP(날짜와 시간, 데이터베이스 timestamp타입과매핑) 가 있다.

@Temporal(TemporalType.TIMESTAMP)
private Date orderDate;     //주문시간

** 다른 프로젝트에서는 난 항상 주문시간/등록시간을 사용할 때 

@CreatedDate을 사용했다. 

@Temporal @CreateDate
날짜 매핑에 사용되는 어노테이션. spring data jpa의 Auditing과 관련된 어노테이션.

@Transient

: 해당 어노테이션이 쓰인 필드는 매핑하지 않으며, 데이터베이스에 저장하지 않고 조회도 하지 않는다. 

-> 보통 객체에 임시로 값을 보관하고 싶을 때 사용한다.

@Transient
private String temp;