JPA
필드와 컬럼 매핑 : 레퍼런스
주씨.
2024. 4. 1. 22:36
728x90
# 매핑 어노테이션
- @Column
- @Enumerated
- @Temporal
- @Lob
- @Transient
- @Access
1. @Column
- 객체 필드를 테이블 컬럼에 매핑한다.
- 속성 중에 name, nullable, unique 가 주로 사용되고, 나머지는 잘 사용되지 않는 편이다.
- nullalbe 의 디폴트값은 true 이다.
@Column(nullable = false)
@Column(unique = true)
@Column(columnDefinition = "varchar(100) default 'EMPTY'")
@Column(length = 400)
- 생성된 DDL
- unique
- alter table Tablename add constraint UK_Xxx unique (username)
- columnDefinition
- data varchar(100) default 'EMPTY'
- unique
- length 는 String 에만 사용할 수 있다.
* 참고
int data1;
data1 integer non null // 생성된 DDL
Integer data2;
data2 integer // 생성된 DDL
@Column
int data3;
data3 integer // 생성된 DDL
- 자바 기본 타입은 null 값을 입력할 수 없다.
- JPA 는 DDL 생성 기능을 사용할 때, int data1 같은 기본 타입에는 not null 제약 조건을 추가한다.
- 반면에 Integer data2 처럼 객체타입이면 null 이 입력될 수 있으므로 not null 제약조건을 설정하지 않는다.
- 그런데 int data3 처럼 @Column 을 사용하면 @Column 은 nullable = true 가 기본값이므로 not null 제약조건을 설정하지 않는다.
- 따라서 자바 기본 타입에 @Column 을 사용하면 nullable = false 로 지정하는 것이 안전하다.
2. @Enumerated
@Enumerated(EnumType.STRING)
@Enumerated(EnumType.ORDINAL)
- EnumType.ORDINAL
- enum 에 정의된 순서대로 DB 에 저장
- EnumType.STRING
- enum 이름 그대로 ADMIN 은 'ADMIN'
* 주의
- 기본값인 ORDINAL 은 주의해서 사용해야 한다.
- ADMIN (0번), USER (1번) 사이에 enum 이 하나 추가되서 ADMIN (0번), NEW (1번), USER (2번)로 설정되면 이제부터 USER 는 2로 저장되지만 기존에 데이터베이스에 저장된 값은 여전히 1로 남아있다.
- 따라서 이런 문제가 발생하지 않는 EnumType.STRING 을 권장한다.
3. @Temporal
@Temporal(TemporalType.DATE)
private Date date;
@Temporal(TemporalType.TIME)
private Date date;
@Temporal(TemporalType.TIMESTAMP)
private Date timestamp;
//== 생성된 DDL ==//
date date,
time time,
timestamp timestamp,
- MySQL 은 timestamp 대신 datetime 을 쓴다.
4. @Lob
- 매핑하는 필드 타입이 문자면 CLOB 으로 매핑하고 나머지는 BLOB 으로 매핑한다.
- CLOB : String, char[], java.sql.CLOB
- BLOB : byte[], java.sql.BLOB
@Lob
private String lobString;
- description 필드처럼, 길이 제한이 없는 필드의 경우에 사용한다.
5. @Transient
- 이 필드는 매핑하지 않는다.
- 따라서 DB에 저장하지 않고 조회하지도 않는다.
- 객체에 임시로 어떤 값을 보관하고 싶을 때 사용한다.
6. @Access
- JPA 가 엔티티 데이터에 접근하는 방식을 지정한다.
- 필드 접근
- AccessType.FIELD 로 지정한다.
- 필드에 직접 접근한다.
- 필드 접근 권한이 private 이어도 접근할 수 있다.
- 프로퍼티 접근
- AccessType.PROPERTY 로 지정한다.
- 접근자(Getter) 를 사용한다.
- 필드 접근 방식과 프로퍼티 접근 방식을 함께 사용할 수도 있다.
@Entity
public class Member {
@Id
private String id;
@Transient
private String firstName;
@Transient
private String lastName;
@Access(AccessType.PROPERTY)
public String getFullName(){
return firstName + lastName;
}
public void setFullName(String fullName) {
// 예제 로직: fullName을 공백으로 나누어 firstName과 lastName을 설정합니다.
String[] parts = fullName.split(" ");
this.firstName = parts[0];
if (parts.length > 1) {
this.lastName = parts[1];
}
}
}
- @Id 가 필드에 있으므로 기본은 필드 접근 방식을 사용하고 getFullName() 만 프로퍼티 접근 방식을 사용한다.
- 따라서 Member 엔티티를 저장하면 member 테이블의 FULLNAME 컬럼에 firstName + lastName 의 결과가 저장된다.