개발서적/자바 ORM 표준 JPA

[자바 ORM 표준 JPA 프로그래밍] 4.7 필드와 컬럼 매핑: 레퍼런스

Reference. 자바 ORM 표준 JPA 프로그래밍

책 목차 및 이전 글

필드와 컬럼 매핑 분류

분류 매핑 어노테이션 설명
필드와 컬럼 매핑 @Column 컬럼을 매핑
제목 없음 @Enumerated 자바의 enum 타입을 매핑
제목 없음 @Temporal 날짜 타입 매핑
제목 없음 @Lob BLOB, CLOB 타입 매핑
제목 없음 @Transient 특정 필드를 데이터베이스에 매핑 안함
기타 @Access JPA가 엔티티 접근하는 방식을 지정

4.7.1 @Column

  • 객체 필드를 테이블 컬럼에 매핑하는 역할
  • 가장 많이 사용되는 기능이며, name, nullable을 주로 사용
  • insertable, updatable 속성은 정보를 읽기만 하고 실수로 변경하는 것을 방지하기 위해 사용

@Column 속성 정리

속성 기능 기본값
name 필드와 매핑할 테이블 컬럼 이름 객체의 필드 이름
insertable (거의 사용X) 엔티티 저장시 이 필드도 같이 저장 false로 설정하면 읽기 전용으로 사용 true
updatable(거의 사용X) 엔티티 수정시 이 필드도 같이 수정 false로 설정하면 읽기 전용으로 사용 true
table(거의 사용X) 하나의 엔티티를 두개 이상의 테이블에 매핑할 때 사용 현재 클래스 매핑 된 테이블
nullable(DDL) null 값의 허용 여부 설정 false로 설정하면 DDL 생성시 not null true
unique(DDL) @Table의 uniqueConstrainsts와 같지만 한 컬럼의 유니크 제약 조건을 걸때 사용 두 컬럼 이상은 uniqueConstrainsts 사용  
columnDefinition(DDL) 데이터베이스 컬럼 정보를 직접 설정 자바 타입과 방언 정보를 통해 적절한 컬럼 타입 설정
length(DDL) 문자 길이 제야 조건, String 타입만 사용 255
precision, scale(DDL) BigDecimal 타입에서 사용 precision은 소수정 포함 전체 자릿수 scale은 소수의 자릿수 double, float 타입에선 적용X 아주 큰 숫자나 정밀한 소수에서 사용 precision = 19
scale = 2
제목 없음    

DDL 생성 속성에 따른 DDL 생성 결과

  • nullable
@Column(nullable = false)
private String data;

//생성 된 DDL
data varchar(255) not null
  • unique
@Column(unique = true)
private String username;

//생성 된 DDL
alter table Tablename add constraint UK_Xxx unique(username)
  • columnDefinition
@Column(columnDefinition = "varchar(100) default 'EMPTY'")
private String data;

//생성 된 DDL
data carchar(100) default 'EMPTY'
  • length
@Column(length = 400)
private String data;

//생성 된 DDL
data varchar(400)
  • precision, scale
@Column(precision = 10, scale = 2)
private BigDecimal cal;

//생성된 DDL
cal numeric(10,2) //H2, PostgreSQL
cal number(10,2)  //오라클
cal decimal(10,2_ //Mysql

<참고>

  • @Column 생략
int data1; 
data integer not null //생성 DLL

Integer data2; 
data2 integer //생성 DLL

@Column
int data3;
data3 Integer //생성 DLL
  • int는 null값 입력 불가능, JPA는 not null 제약 조건을 추가
  • Integer는 null값 입력 가능, JPA는 null 제약 조건 추가
  • @Column을 사용하면 nullable = true가 기본값이므로 null 제약 조건 추가 → 자바 기본타입nullable = false안전

 

4.7.2 @Enumerated

@Enumerated 속성 정리

속성 기능 기본값
value - EnumType.ORDINAL: enum 순서를 DB 저장
- EnumType.STRING: enum 이름을 DB 저장
EnumType.ORDINAL

@Enumerated 사용 예

//Enum
enum RoleType{
		ADMIN, USER
}

//Entity
@Enumerated(EnumType.STRING)
private RoleType roleType;

//main(실제 호출)
member.setRoleType(RoleType.ADMIN); // DB에 문자 ADMIN으로 저장
  • EnumType.ORDINAL: enum에 정의된 순서 ADMIN은 0, USER는 1이 저장
    • 장점: 데이터베이스에 저장되는 데이터 크기가 작음
    • 단점: 이미 저장된 enum 순서를 변경하기 어려움
  • EnumType.STRING: STRING은 enum 이름 그대로 저장(ADMIN: 'ADMIN', USER:'USER')
    • 장점: enum 순서가 바뀌거나 추가되어도 안전
    • 단점: 데이터베이스에 데이터 크기가 ORDINAL에 비해 큼

<주의>

  • enum에 값이 추가되어 순서가 변경되는 상황에 문제 발생
    • ADMIN(0), USER(1)ADMIN(0), NEW(1), USER(2)인 경우, DB에선 기존 데이터 1이 USER
    • EnumType.STRING을 권장

4.7.3 @TEMPORAL

  • 날짜 타입(java.util.Date, java.util.Calendar)을 매핑할 때 사용

@Temporal 속성 정리

속성 기능 기본값
value - TemporalType.DATE: 날짜 DB date타입과 매핑
(예: 2013-10-11)
- TemporalType.TIME: 시간, DB time 타입과 매핑
(예: 12:23:59)
- TemporalType.TIMESTAMP: 날짜와 시간, DB timestamp 타입과 매핑
(예: 2013-10-11 12:23:59)
TemporalType 필수 지정

@Temporal 사용 예

@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
  • @Temporal을 생략하면 자바 Date와 유사한 timestamp로 정의
    • datetime: MySQL
    • timestamp: H2, 오라클, PostgreSQL

4.7.4 @Lob

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

속성 정리

  • @Lob에는 지정할 수 있는 속성이 없음
    • CLOB: 필드 타입이 문자면 매핑 ( String, char[], java.sql.CLOB )
    • BLOB: 나머지 타입 매핑 (byte[], java.sql.BLOB)

@Lob 사용 예

@Lob
private String lobString;

@Lob
private byte[] lobByte;

//ddl 결과
//오라클
lobString clob,
lobByte blob,

//Mysql
lobString longtext,
lobByte longblob,

//PostgreSQL
lobString text,
lobByte oid,

4.7.5 @Transient

  • 객체에 임시로 어떤 값을 보관하고 싶을때 사용 ( 매핑 X )

4.7.6 @Access

  • JPA가 엔티티 데이터에 접근하는 방식을 지정
  • 필드 접근: AccessType.FIELD로 지정 ( private이어도 접근 가능)
  • 프로퍼티 접근: AccessType.PROPERTY로 지정, 접근자( Getter)를 사용
  • @Access를 설정하지 않으면 @Id의 기준으로 접근 방식 설정

필드 접근 사용 예

  • @Id가 필드에 있으므로 @Access(AccessType.FIELD) 생략 가능
@Entity
@Access(AccessType.FIELD)
public class Member {

		@Id
		private String id;

		private String data1;
		private String data2;
		...
}

프로퍼티 접근 사용 예

  • @Id가 프로퍼티에 있으므로 @Access(AccessType.PROPERTY) 생략 가능
@Entity
@Access(AccessType.PROPERTY)
public class 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;
		}
}

필드, 프로퍼티 접근 및 Transient 사용 예

  • @Id가 필드에 있으므로 기본은 필드 접근 방식 사용
  • getFullName() 만 프로퍼티 접근 방식 사용 ( FULLNAME 컬럼 생성 )
@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;
		}
		...
}