이 글은 김영한 님의 저서 「자바 ORM 표준 JPA 프로그래밍」을 학습한 내용을 정리한 글입니다. 모든 출처는 해당 저서에 있습니다.
| 분류 | 매핑 어노테이션 | 설명 |
|---|---|---|
| 필드와 컬럼 매핑 | @Colunm | 컬럼 매핑 |
@Enumerated | 자바의 enum 타입 매핑 | |
@Temporal | 날짜 타입 매핑 | |
@Lob | BLOB, CLOB 타입 매핑 | |
@Transient | 특정 필드를 데이터베이스에 매핑 x | |
| 기타 | @Access | JPA의 엔티티 접근 방식 지정 |
@Column객체 필드를 테이블 컬럼에 매핑
| 속성 | 기능 | 기본값 |
|---|---|---|
| name | 필드와 매핑할 테이블 컬럼 이름 | 객체의 필드 이름 |
| insertable (거의 사용 x) | ◾ 엔티티 저장 시 같이 저장 ◾ false 옵션 - 설정 시 데이터베이스에 저장 x - 읽기 전용일 때 사용 | true |
| updatable (거의 사용 x) | ◾ 엔티티 수정 시 같이 수정 ◾ false 옵션 - 설정 시 데이터베이스에 수정 x - 읽기 전용일 때 사용 | true |
| table (거의 사용 x) | ◾ 하나의 엔티티를 두 개 이상 테이블에 매핑할 때 사용 ◾ 지정한 필드를 다른 테이블에 매핑 가능 | 현재 클래스가 매핑된 테이블 |
| nullable (DDL) | ◾ null 값 허용 여부 설정 ◾ false 설정 → DDL 생성 시 not null 제약조건 추가 | true |
| unique (DDL) | ◾ @Table의 uniqueConstaints와 같음◾ 한 컬럼에 간단한 유니크 제약조건 추가 할 때 사용 ◾ 두 컬럼 이상 사용하여 유니크 제약조건 사용 위해 클래스 레벨에서 @Table.uniqueConstraints 사용 | |
| columnDefinition (DDL) | 데이터베이스 컬럼 정보 직접 제공 | 필드 자바 타입 + 방언 정보 → 적절한 컬럼 타입 생성 |
| length (DDL) | ◾ 문자 길이 제약조건 ◾ String 타입에만 사용 | 255 |
| precision, scale (DDL) | ◾ BigDecimal 타입에서 사용 (BigInteger도 사용 가능) ◾ precision : 소수점 포함 전체 자릿수◾ scale : 소수의 자릿수◾ double, float 타입 적용 x ◾ 아주 큰 숫자나 정밀한 소수를 다루어야 할 때 사용 | precision=19, scale=2 |
@Column(nullable = false)
private String data;
data varchar(255) not null
@Column(unique = true)
private String username;
alter table Tablename add constraint UK_Xxx unique (username)
@Column(columnDefinition = "varchar(100) default 'EMPTY'")
private String data;
data varchar(100) default 'EMPTY'
@Column(length = 400)
private String data;
data varchar(400)
@Column(precision = 10, scale = 2)
private BigDecimal cal;
cal numeric(10,2) //H2, PostgreSQL
cal number(10,2) //ORACLE
cal decimal(10,2) //MySQL
int data1; //@Column 생략, 자바 기본 타입
data1 integer not null //생성된 DDL → null 값 허용 x
Integer data2; //@Column 생략, 객체 타입
data2 integer //생성된 DDL → null 값 허용
@Column //'nullable = true' 기본
int data3; //@Column 사용, 자바 기본 타입
data3 integer //생성된 DDL
| 기본 타입 | 객체 타입 | @Column 사용 | |
|---|---|---|---|
| null 값 허용 | X | O | nallable = true |
| not null 제약조건 | O | X | X |
∴ 기본 타입에 @Column 사용시 nullable = false로 지정하는 것이 안전함
@Enumerated자바의 enum 타입 매핑
| 속성 | 기능 | 기본값 |
|---|---|---|
| value | ◾ EnumType.ORDINAL : enum 순서 데이터베이스에 저장ex) ADMIN : 0, USER : 1- 장점 : 데이터베이스에 저장되는 데이터 크기 작음 - 단점 : 이미 저장된 enum 순서 변경 불가 ◾ EnumType.STRING : enum 이름 데이터베이스에 저장ex) ADMIN : ADMIN, USER : USER- 장점 : enum 저장 순서 변경 및 enum 추가 시 안전 - 단점 : 데이터베이스 저장 데이터 크기가 ORDINAL에 비해 큼 | EnumType.ORDINAL |
💡 주의 사항
ORDINAL을 사용할 경우, 만약 ADMIN(0번), USER(1번) 사이에 enum을 추가하여 ADMIN(0번), NEW(1번), USER(2번)가 되면, USER는 2로 저장되지만 기존 데이터베이스에 저장된 값은 변경되지 않고 1이므로 값이 일치하지 않는 문제 발생
→EnumType.String사용 권장
enum RoleType {
ADMIN, USER
}
@Enumerated(EnumType.STRING)
private RoleType roleType;
member.setRoleType(RoleType.ADMIN); //DB에 문자 ADMIN으로 저장
@Temporal날짜 타입(
java.util.Date,java.util.Calendar) 매핑
| 속성 | 기능 | 기본값 |
|---|---|---|
| value | ◾ TemporalType.DATE : 날짜→ 데이터베이스 date 타입과 매핑ex) 2020 - 10 - 11 ◾ TemporalType.TIME : 시간→ 데이터베이스 time 타입과 매핑ex) 11:11:11 ◾ TemporalType.TIMESTAMP : 날짜와 시간→ 데이터베이스 timestamp 타입과 매핑ex) 2020 - 10 - 11 11:11:11 | timestamp |
@Temporal(TemporalType.DATE)
private Date date; //날짜
@Temporal(TemporalType.TIME)
private Date time; //시간
@Temporal(TemporalType.TIMESTAMP)
private Date timestamp; //날짜와 시간
date date,
time time,
timestamp timestamp,
...
timestamp로 정의datetime : MySQLtimestamp : H2, ORACLE, PostgreSQ@Lob데이터베이스
BLOB,CLOB타입과 매핑
String, char[], java.sql.CLOB byte[], java.sql.BLOB@Lob
private String lobString;
@Lob
private byte[] lobByte;
//ORACLE
lobString clob,
lobByte blob,
//MySQL
lobString longtext,
lobByte longblob,
//PostgreSQL
lobString text,
lobByte old,
...
@Transient객체에 어떤 값을 임시로 보관하고 싶을 때 사용
@Transient
private Integer temp;
@AccessJPA의 엔티티 데이터 접근 방식 지정
@Id 위치 기준으로 접근 방식 설정AccessType.FIELDprivate이어도 접근 가능@Id가 필드에 존재 = @Access(AccessType.FIELD) 설정@Access 생략 가능@Entity
@Access(AccessType.FIELD) //생략 가능
public clss Member {
@Id
private String id;
private String data1;
private String data2;
...
}
AccessType.PROPERTYGetter) 사용하여 접근@Id가 프로퍼티에 존재 = @Access(AccessType.PROPERTY 설정@Access 생략 가능@Entity
@Access(AccessType.PROPERTY) //생략 가능
public clss Member {
private String id;
private String data1;
private String data2;
@Id
public String getId() {
return id;
}
@Column
public String getData1() {
return data1;
}
public String getData2() {
return data2;
}
...
}
@Entity
public clss Member {
@Id //필드 접근 방식
private String id;
@Transient
private String firstName;
@Transient
private String lastName;
@Access(AccessType.PROPERTY) //프로퍼티 접근 방식
public String getFullName() {
return firstName + lastName;
}
...
}