[JPA] Chapter 4. 엔티티 매핑 3 - 필드-컬럼

들어가기 앞서

이 글은 김영한 님의 저서 「자바 ORM 표준 JPA 프로그래밍」을 학습한 내용을 정리한 글입니다. 모든 출처는 해당 저서에 있습니다.


4.5 필드와 컬럼 매핑: 레퍼런스

📝 필드와 컬럼 매핑 분류

분류매핑 어노테이션설명
필드와 컬럼 매핑@Colunm컬럼 매핑
@Enumerated자바의 enum 타입 매핑
@Temporal날짜 타입 매핑
@LobBLOB, CLOB 타입 매핑
@Transient특정 필드를 데이터베이스에 매핑 x
기타@AccessJPA의 엔티티 접근 방식 지정

4.5.1 @Column

객체 필드를 테이블 컬럼에 매핑

✅ 속성

속성기능기본값
name필드와 매핑할 테이블 컬럼 이름객체의 필드 이름
insertable
(거의 사용 x)
◾ 엔티티 저장 시 같이 저장
◾ false 옵션
   - 설정 시 데이터베이스에 저장 x
   - 읽기 전용일 때 사용
true
updatable
(거의 사용 x)
◾ 엔티티 수정 시 같이 수정
◾ false 옵션
   - 설정 시 데이터베이스에 수정 x
   - 읽기 전용일 때 사용
true
table
(거의 사용 x)
◾ 하나의 엔티티를 두 개 이상 테이블에 매핑할 때 사용
◾ 지정한 필드를 다른 테이블에 매핑 가능
현재 클래스가 매핑된 테이블
nullable
(DDL)
◾ null 값 허용 여부 설정
◾ false 설정 → DDL 생성 시 not null 제약조건 추가
true
unique
(DDL)
@TableuniqueConstaints와 같음
◾ 한 컬럼에 간단한 유니크 제약조건 추가 할 때 사용
◾ 두 컬럼 이상 사용하여 유니크 제약조건 사용 위해
   클래스 레벨에서 @Table.uniqueConstraints 사용
columnDefinition
(DDL)
데이터베이스 컬럼 정보 직접 제공필드 자바 타입 + 방언 정보
→ 적절한 컬럼 타입 생성
length
(DDL)
◾ 문자 길이 제약조건
◾ String 타입에만 사용
255
precision, scale
(DDL)
◾ BigDecimal 타입에서 사용
   (BigInteger도 사용 가능)
precision : 소수점 포함 전체 자릿수
scale : 소수의 자릿수
◾ double, float 타입 적용 x
◾ 아주 큰 숫자나 정밀한 소수를 다루어야 할 때 사용
precision=19, scale=2

✅ DDL 생성 속성에 따라 생성되는 DDL

📝 nullable

  • 매핑 코드
@Column(nullable = false)
private String data;
  • 결과
data varchar(255) not null

📝 unique

  • 매핑 코드
@Column(unique = true)
private String username;
  • 결과
alter table Tablename add constraint UK_Xxx unique (username)

📝 columnDefinition

  • 매핑 코드
@Column(columnDefinition = "varchar(100) default 'EMPTY'")
private String data;
  • 결과
data varchar(100) default 'EMPTY'

📝 length

  • 매핑 코드
@Column(length = 400)
private String data;
  • 결과
data varchar(400)

📝 precision, scale

  • 매핑 코드
@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 값 허용XOnallable = true
not null
제약조건
OXX

∴ 기본 타입에 @Column 사용시 nullable = false로 지정하는 것이 안전함



4.5.2 @Enumerated

자바의 enum 타입 매핑

✅ 속성

속성기능기본값
valueEnumType.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 클래스

enum RoleType {
    ADMIN, USER
}

📝 enum 이름 매핑

@Enumerated(EnumType.STRING)
private RoleType roleType;

📝 enum 사용

member.setRoleType(RoleType.ADMIN);  //DB에 문자 ADMIN으로 저장


4.5.3 @Temporal

날짜 타입(java.util.Date, java.util.Calendar) 매핑

✅ 속성

속성기능기본값
valueTemporalType.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; //날짜와 시간

📝 생성된 DDL

date date,
time time,
timestamp timestamp,
...

✅ 생략

  • timestamp로 정의
  • 데이터베이스 방언에 따라 DDL이 자동 생성 됨
    • datetime : MySQL
    • timestamp : H2, ORACLE, PostgreSQ


4.5.4 @Lob

데이터베이스 BLOB, CLOB 타입과 매핑


✅ 속성

  • 지정 속성 존재 x
  • 매핑하는 필드 타입에 따라 DB의 BLOB, CLOB과 매핑
    • CLOB : 문자 ex) String, char[], java.sql.CLOB
    • BLOB : 그 외 ex) byte[], java.sql.BLOB

✅ 사용 예

📝 매핑

@Lob
private String lobString;

@Lob
private byte[] lobByte;

📝 생성된 DDL

//ORACLE
lobString clob,
lobByte blob,

//MySQL
lobString longtext,
lobByte longblob,

//PostgreSQL
lobString text,
lobByte old,
...


4.5.5 @Transient

객체에 어떤 값을 임시로 보관하고 싶을 때 사용

  • 매핑 x → 데이터베이스에 저장 x, 조회 x

✅ 사용 예

@Transient
private Integer temp;


4.5.6 @Access

JPA의 엔티티 데이터 접근 방식 지정

  • 미설정 시 @Id 위치 기준으로 접근 방식 설정
  • 접근 방식 동시 사용 가능

✅ 필드 접근

  • 지정 : AccessType.FIELD
  • 필드에 직접 접근
  • 필드 접근 권한이 private이어도 접근 가능
  • @Id가 필드에 존재 = @Access(AccessType.FIELD) 설정
    @Access 생략 가능
@Entity
@Access(AccessType.FIELD)  //생략 가능
public clss Member {

    @Id
    private String id;
    
    private String data1;
    private String data2;
    ...
}

✅ 프로퍼티 접근

  • 지정 : AccessType.PROPERTY
  • 접근자(Getter) 사용하여 접근
  • @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;
    }
    ...
}

좋은 웹페이지 즐겨찾기