[Spring][JPA]41 엔티티 매핑, 필드 컬럼 매핑, 기본키 매핑 등 현재까지 주요 어노테이션

Category
Author
Tags
PinOnMain
1 more property
핵심 어노테이션

@Entity

@Entity 어노테이션이 붙은 클래스는 JPA가 관리하는 엔티티이다
JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션이 필수다
기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자)
final 클래스, enum, interface, inner 클래스 사용 X
저장할 필드에 final 사용 X
name 속성을 사용하면 JPA에서 사용할 엔티티 이름을 지정할 수 있다.
기본값은 클래스 이름을 그대로 사용한다
예시:
@Entity public class Member { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; private String name; Member(){}// 생략하면 자동으로 생성 but, 다른 생성자가 있으면 자동 생성 안됨 }
Java
복사

@Table

@Table 어노테이션은 엔티티와 매핑할 테이블을 지정한다.
name 속성으로 매핑할 테이블 이름 지정이 가능하다
기본값은 엔티티 이름이다
예시 :
@Entity @Table(name = MEMBERS) public class Member { @Id @GeneratedValue @Column(name = "MEMBER_ID") private Long id; private String name; Member(){}// 생략하면 자동으로 생성 but, 다른 생성자가 있으면 자동 생성 안됨 }
Java
복사

필드와 칼럼 매핑

@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… }
Java
복사

1. @Column

속성
설명
기본값
name
필드와 매핑할 테이블의 컬럼 이름
객체의 필드 이름
insertable,updatable
등록, 변경 가능 여부
TRUE
nullable(DDL)
null 값의 허용 여부를 설정한다. false로 설정하면 DDL 생성 시에 not null 제약조건이 붙는다.
unique(DDL)
@Table의 uniqueConstraints와 같지만 한 컬럼에 간단히 유니크 제약조건을 걸 때 사용한다.
columnDefinition(DDL)
데이터베이스 컬럼 정보를 직접 줄 수 있다.ex) varchar(100) default ‘EMPTY'
필드의 자바 타입과방언 정보를 사용해
length(DDL)
문자 길이 제약조건, String 타입에만 사용한다.
255
precision,scale(DDL)
BigDecimal 타입에서 사용한다(BigInteger도 사용할 수 있다).precision은 소수점을 포함한 전체 자 릿수를, scale은 소수의 자릿수다. 참고로 double, float 타입에는 적용되지 않는다. 아주 큰 숫자나정 밀한 소수를 다루어야 할 때만 사용한다
precision=19,scale=2

2. @Enumerated

자바 enum 타입을 매핑할 때 사용
속성
설명
기본값
value
- EnumType.ORDINAL: enum 순서를 데이터베이스에 저장- EnumType.STRING: enum 이름을 데이터베이스에 저장
EnumType.ORDINAL
기본값은 ORDINAL이지만, ORDINAL을 사용하지 않는 게 좋다.
예를 들어
public enum RollType { ACTOR, PROGRAMMER, CEO// 0,1,2 }
Java
복사
위와 같은 enum 타입 클래스를 정의했다고 하자.
ACTOR, PROGRAMMER, CEO는 순서대로 0,1,2를 나타낸다.
만약 value 속성을 @Enumerated(value = EnumType.ORDINAL)로 하면 순서인 0,1,2를 저장한다
이때 RollType이 아래와 같이 변한다고 하자.
public enum RollType { DANCER, ACTOR, PROGRAMMER, CEO// 0,1,2,3 }
Java
복사
DANCER라는 값이 앞에 추가되면서 기존의 순서가 깨져버린다. 이렇게 되면 데이터베이스에 저장된 ACTOR=0, PROGRAMMER=1, CEO=2 등의 순서와 정합성이 맞지 않게 된다.
반면 EnumType.STRING을 사용하면 enum 이름 그대로 저장하기 때문에 enum 값이 변하더라도 문제가 없다.

@Temporal

날짜 타입(java.util.Date, java.util.Calender)을 매핑할 때 사용
최신 하이버네이트가 지원하는 LocalDate, LocalDateTime을 사용할 때는 생략 가능하다.
속성
설명
기본값
value
• TemporalType.DATE: 날짜, 데이터베이스 date 타입과 매핑(예: 2013–10–11)• TemporalType.TIME: 시간, 데이터베이스 time 타입과 매핑(예: 11:11:11)• TemporalType.TIMESTAMP: 날짜와 시간, 데이터베이 스timestamp 타입과 매핑(예: 2013–10–11 11:11:11)

@Lob

데이터베이스 BLOB, CLOB 타입과 매핑
지정할 수 있는 속성이 없다
매핑하는 필드 타입이 문자면 CLOB 매핑, 나머지는 BLOB 매핑

@Transient

해당 어노테이션이 붙은 필드는 매핑하지 않는다
따라서 데이터베이스에 저장되지도, 조회되지도 않는다
주로 메모리상에서만 임시로 값을 보관하고 싶을 때 사용한다

기본키 매핑 어노테이션

직접 기본키를 할당하려면 @Id 어노테이션만 사용
자동 생성하려면 @GeneratedValue 어노테이션 사용

@GeneratedValue

IDENTITY 전략

기본 키 생성을 데이터베이스에 위임
주로 MySQL, PostgreSQL, SQL Server, DB2 등에서 사용 (예시 : MySQL의 AUTO_INCREMENT)
JPA는 보통 트랜잭션 커밋 시점에 INSERT SQL을 실행한다
AUTO_INCREMENT는 데이터베이스에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있다
IDENTITY 전략은 em.persist() 시점에 즉시 INSERT SQL 실행 후 DB에서 식별자를 조회한다
예시 :
@Entity public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; ...
Java
복사

SEQUENCE 전략

유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트(예시 : 오라클 시퀀스)
오라클, PostgreSQL, DB2, H2 데이터베이스 등에서 사용
예시 :
@Entity @SequenceGenerator( name =MEMBER_SEQ_GENERATOR", sequenceName =MEMBER_SEQ", //매핑할 데이터베이스 시퀀스 이름 initialValue = 1, allocationSize = 1) public class Member { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR") private Long id;
Java
복사
속성
설명
기본값
name
식별자 생성기 이름
필수
sequenceName
데이터베이스에 등록되어 있는 시퀀스 이름
hibernate_sequence
initialValue
DDL 생성 시에만 사용됨, 시퀀스 DDL을 생성할 때 처음 1 시작하는수를 지정한다.
1
allocationSize
시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용됨)데이터베이스 시퀀스 값이 하나씩 증가하도록 설정되어 있으면 이 값을 반드시 1로 설정해야 한다
50
catalog, schema
데이터베이스 catalog, schema 이름

TABLE 전략

키 생성 전용 테이블을 하나 만들어 데이터베이스 시퀀스를 흉내 내는 전략
모든 데이터베이스에 적용 가능하지만 성능이 좋지 않다
TABLE 전략은 키 생성 전용 테이블을 하나 만들고 여기에 이름과 값으로 사용할 컬럼을 만들어 데이터 베이스 시퀀스를 흉내 내는 전략이다. 이 전략은 테이블을 사용하므로 모든 데이터베이스에 적용할 수 있다.
TABLE 전략은 시퀀스 대신에 테이블을 사용한다는 것만 제외하면 SEQUENCE 전략과 내부 동작방식이 같다.
@TableGenerator 어노테이션에 적용할 수 있는 속성은 아래와 같다. (기본 값은 하이버네이트 기준)
name :
식별자 생성기 이름을 설정가능하며 기본 값이 필수
table:
키생성 테이블명
기본값 = hibernate_sequence
pkColumnName :
시퀀스 컬럼명
기본값 = sequence_name
valueColumnName :
시퀀스 값 컬럼명
기본값 = next_val
pkColumnValue :
키로 사용할 값 이름
기본값 = Entity 명
initialValue :
초기 값, 마지막으로 생성된 값이 기 준이다.
기본값 = 0
allocationSize :
시퀀스 한 번 호출에 증가하는 수 (성능 최적화에 사용됨)
기본값 = 50
catalog, schema :
데이터베이스 catalog,schema 명
uniqueConstraints(DDL) :
유니크 제약 조건을 지정할 수 있다.
TABLE 전략은 SELECT 쿼리로 값을 조회하고 UPDATE 쿼리로 값을 증가시킨다. SEQUENCE 전략과 비교했을때 DB와 한 번 더 통신하는 것이 단점이다. TABLE 전략 최적화는 @TableGenerator.allocationSize 를 사용하면 된다. 해당 어노테이션을 사용하면 SEQUENCE 전략과 같아진다.
Core Annotations
@entity on Entity class -> make members persistence(MANAGED)
@table(name = "blog") -> make class as DB table
@id -> make PK
@GeneratedValue -> strategy of PK option
- TABLE -> make table for only PK?
- SEQUENCE -> need to create sequence as Oracle DB, H2, PostgreSQL etc..
- IDENTITY -> PK creation assign to DB as MySQL, MySQL DB increase num by auto_increment
- AUTO -> JPA decides by DATA Type
-- if, UUID -> UUID Generator
-- if, Numerial(int, long...) -> Default Sequence but there's no Sequence like MySQL -> choose Table Automatically.
@column -> make field as DB column with attributes
@MappedSuperclass -> make class as static variable for only Entity object(DB's row)
@EntityListeners(AuditingEntityListener.class) -> when DB operation happening, this class's working dynamically with operation like insert User row, Listners action right away with it.
- follow details : https://mopil.tistory.com/46
@TemporaL(TemporalType.TIMESTAMP) <- default TIMESTAMP
- Optional type
-- DATE(YYYY-MM-DD)
-- TIME(HH:MM:SS)
-- TIMESTAMP(YYYY-MM-DD HH:MM:SS) as DATE+TIME
date는 날짜까지만 나타나기때문에 시간분초까지 나타나는 datetime타입을 선택.
게시글이기 때문에 장문이 들어 올 수 있어 text타입 → @column(columnDefinition = "TEXT")