JPA 필드와 컬럼 매핑
📝 필드와 컬럼 매핑 종류
@Column : 컬럼을 매핑
@Enumerated : 자바의 enum 타입을 매핑
@Temporal : 날짜 타입을 매핑
@Lob : BLOB, CLOB 타입을 매핑
@Transient : 특정 필드를 DB에 매핑하지 않음
🧐 @Column 은 무엇인가?
객체 필드를 테이블 컬럼에 매핑하는 어노테이션이다.
@Column 속성
- name : 필드와 매핑할 테이블의 컬럼 이름. 기본값은 객체의 필드 이름
@Column(name = "name")
private String username;
//생성된 DDL
create table 테이블명 (
name varchar(255) not null,
...
)
- insertable : 엔티티 저장 시 이 필드도 같이 저장. 기본값은 true. 읽기 전용으로 쓸 때 false로 한다. (거의 사용하지 않음)
- updatable : 엔티티 수정 시 이 필드도 같이 수정. 기본값은 true. 읽기 전용일 때 false로 한다. (거의 사용하지 않음)
- table : 하나의 엔티티를 두 개 이상의 테이블에 매핑할 때 사용. 기본값은 현재 클래스가 매핑된 테이블. (거의 사용하지 않음)
- nullable : null값의 허용 여부 설정. 기본값은 true. false로 하면 DDL 생성 시 nuo null 제약조건 추가. (DDL)
@Column(nullable = false)
private String data;
//생성된 DDL
data varchar(255) not null
- unique : @Table의 uniqueConstraints와 같지만 컬럼에 간단히 유니크 제약조건 걸 때 사용. (DDL)
@Column(unique = true)
private String username;
//생성된 DDL
alter table Tablename
add constraint UK_XXX unique (username)
- columnDefinition : DB 컬럼 정보를 직접 줄 수 있음. 기본값은 필드의 자바 타입과 방언 정보를 사용해 적절한 컬럼 타입을 생성(DDL)
@Column(columnDefinition = "varchar(100) default 'EMPTY'")
private String data;
//생성된 DDL
data varchar(100) default 'EMPTY'
- length : 문자 길이 제약조건, String 타입에만 사용. 기본값 255. (DDL)
@Column(length = 400)
private String data;
//생성된 DDL
data varchar(400)
- precision, scale : BigDecimal 또는 BigInteger타입에서 사용. precision은 소수점을 포함한 전체 자릿수, scale은 소수의 자릿수. double과 float 타입에는 적용되지 않는다. 아주 큰 숫자나 정밀한 소수 다룰때만 사용. 기본값은 precision = 19, scale = 2. (DDL)
@Column(precision = 10, scale = 2)
private BigDecimal cal;
//생성된 DDL
cal numeric(10,2) //H2, PostgreSQL
cal number(10,2) //오라클
cal number(10,2) //MySQL
🧐 @Enumerated 은 무엇인가?
자바의 enum 타입을 매핑할 때 사용한다.
속성
- value : 2가지 기능이 있는데 EnumType.ORDINAL 과 EnumType.STRING이 있다. 기본값은 ORDINAL이다.
EnumType.ORDINAL : enum 순서를 DB에 저장.
- 장점 : DB에 저장되는 데이터 크기가 작다.
- 단점 : 저장된 enum의 순서를 변경할 수 없다. (확장성 문제)
EnumType.STRING : enum 이름을 DB에 저장.
- 장점 : 저장된 enum의 순서가 바뀌거나 추가되어도 안전하다.
- 단점 : DB에 저장되는 데이터 크기가 상대적으로 크다.
예시
enum 클래스
enum RoleType {
ADMIN, USER
}
엔티티
@Enumerated(EnumType.STRING)
private RoleType roleType;
이렇게 만들고 member.setRoleType(RoleType.ADMIN); 을 하게된다면 DB에 문자인 "ADMIN" 이 저장된다.
만약 타입을 ORDINAL로 했다면 "ADMIN"의 순서가 처음이므로 0 이 저장되었을 것이다.
🧐 @Temporal 은 무엇인가?
날짜 타입(java.util.Date, java.util.Calendar)을 매핑할 때 사용한다.
속성
- value : 3가지 TemporalType인 DATE, TIME, TIMESTAMP 가 있다. 이것은 필수로 지정해야 한다.
예시
@Temporal(TemporalType.DATE)
private Date date; // 날짜
@Temporal(TemporalType.TIME)
private Date time; // 시간
@Temporal(TemporalType.TIMESTAMP)
private Date timestamp; // 날짜와 시간
//==생성된 DDL==//
date date,
time time,
timestamp timestamp
자바의 Date 타입에는 년월일 시분초가 있는데, DB에서는 나뉘어져 있다.
🧐 @Lob 은 무엇인가?
DB의 BLOB, CLOB 타입과 매핑한다.
여기에는 지정할 수 있는 속성이 없다. 대신 매핑하는 필드 타입이 문자면 CLOB, 나머지는 BLOB로 매핑한다.
이거는 그냥 어노테이션만 붙이면 되기에 예시는 생략했다.
🧐 @Transient 은 무엇인가?
이 필드는 DB와 매핑하지 않고, 조회도 하지 않는다.
객체에 임시로 어떤 값을 보관하고 싶을 때 사용한다.
좀 더 자세히 말하자면, 단순히 컬럼을 제외하는것이 아니라 영속 대상에서 제외시키기 위해 사용한다고 보면 된다.
🧐 @Access 은 무엇인가?
JPA가 엔티티 데이터에 접근하는 방식을 지정한다.
접근하는 방식은 2가지로 다음과 같다.
- 필드 접근 : AccessType.FIELD로 지정. 말 그대로 필드에 직접 접근한다. 필드가 private이어도 접근한다.
- 프로퍼티 접근 : AccessType.PROPERTY로 지정. 접근자(Getter)를 사용.
이 어노테이션을 설정하지 않으면 @Id의 위치를 기준으로 접근 방식이 설정된다.
즉, @Id가 필드에 있으면 @Access(AccessType.FIELD)로 설정한 것과 같다.
@Id가 프로퍼티에 있으면 @Access(AccessType.PROPERTY)를 설정한 것과 같다.
따라서 이 어노테이션은 생략해도 된다.
예시
@Entity
@Access(AccessType.FIELD) // 생략해도됨.
public class Member {
// 필드에 @Id가 있음
@Id
private String id;
...
}
@Entity
@Access(AccessType.PROPERTY) // 생략해도 됨.
public class Member {
private String id;
private String data1;
// @Id가 프로퍼티에 있다
@Id
public String getId() {
return id;
}
@Column
public String getData1() {
return data1;
}
}
자바 ORM 표준 JPA 프로그래밍 / 김영한 지음 / 에이콘출판주식회사 출판
자바 ORM 표준 JPA 프로그래밍 - 기본편 / 김영한 / 인프런 강의
https://gmoon92.github.io/jpa/2019/09/29/what-is-the-transient-annotation-used-for-in-jpa.html