[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)
◾ @Table의 uniqueConstaints와 같음
◾ 한 컬럼에 간단한 유니크 제약조건 추가 할 때 사용
◾ 두 컬럼 이상 사용하여 유니크 제약조건 사용 위해
   클래스 레벨에서 @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 타입 매핑

✅ 속성

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

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) 매핑

✅ 속성

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

📝 생성된 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;
    }
    ...
}

좋은 웹페이지 즐겨찾기