Sun's Blog

자바 ORM 표준 JPA 프로그래밍 4장 본문

Book/자바 ORM 표준 JPA 프로그래밍

자바 ORM 표준 JPA 프로그래밍 4장

버스는그만 2023. 6. 21. 14:33

@Entity

JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션을 필수로 붙여야 한다.

속성값

속성 기능 기본값
name JPA에서 사용할 엔티티 이름을 지정한다. 보통 기본값인 클래스 이름을 사용한다. 만약  해당 클래스의 이름

주의사항

  • 기본 생성자는 필수(파라미터가 없는 public 또는 protected 생성자)
  • final 클래스, enum, interface, inner 클래스에는 사용할 수 없다.
  • 자장할 필드에 final을 사용하면 안 된다.

@Table

@Table은 엔티티와 매핑할 테이블을 지정한다. 생략하면 매핑한 엔티티 이름을 테이블 이름으로 사용한다.

속성 기능 기본값
name 매핑할 테이블 이름 엔티티 이름을 사용한다.
catelog catalog 기능이 있는 데이터베이스에서 catalog를 매핑한다  
schema schema 기능이 있는 데이터베이스에서 schema를 매핑한다  
uniqueConstrains(DDL) DDL 생성 시에는 유니크 제약 조건을 만든다. 2개 이상의 복합 유니크 제약 조건도 만들 수 있다.  

yml, properties 혹은 xml에 hibernate.hb,2ddl.auto=create 속성을 추가하면 애플리케이션 실행 시점에 데이터베이스 테이블을 자동으로 생성한다. hibernate.show_sql=true하면 생성한 SQL문을 콘솔창에 출력할 수 있다.

 hibernate.hb,2ddl.auto

옵션 설명
create 기존 테이블을 삭제하고 새로 생성한다. DROP + CREATE
create-drop create 속성에 추가로 애플리케이션을 종료할 때 생성한 DDL을 제거한다. DROP, CREATE, DROP 순서
update 데이터베이스 테이블과 엔티티 매핑정보를 비교해서 변경 사항만 수정한다.
validate 데이터베이스 테이블과 매핑정보를 비교해서 차이가 있으면 경고를 남기고 애플리케이션을 실행하지 않는다. 이 설정은 DDL을 수정하지 않는다.
none 자동 생성 기능을 사용하지 않는다.

기본 키 매핑

JPA가 제공하는 데이터베이스 기본 키 생성 전략은 다음과 같다.

  • 직접 할당: 기본 키를 애플리케이션에서 직접 할당한다.
  • 가동 생성: 대리키 사용 방식
    • IDENTITY: 기본 키 생성을 데이터베이스에 위임한다.
    • SEQUENCE: 데이터베이스 스퀀스를 사용해서 기본 키를 할당한다.
    • TABLE: 키 생성 테이블을 사용한다.

키 생성 전략을 사용하려면 hibernate.id.new_generator_mapping=true 속성을 반드시 추가해야 한다.(SpringBoot 2,0에서는 Default 값이 True로 바껴서 SpringBoot 2,0에서는 따로 추가할 필요가 없다.)

@Id

@Id가 적용 가능 자바 타입은 다음과 같다.

  • 기본형
  • 래퍼형
  • String
  • java.util.Date
  • java.sql.Date
  • java.math.BigDecimal
  • java.math.BigInteger

IDENTITY 전략

IDENTITY 전략은 기본 키 생성을 데이터베이스에 위임하는 전략이다.(Auto Increment)

@Id
@GeneratedValue(stragegy = GenerationType.IDENTITY)
private Long id;

엔티티가 영속 상태가 되려면 식별자가 반드시 필요하다. 그런데 IDENTITY 식별자 생성 전략은 엔티티를 데이터베이스에 저장해야 식별자를 구할 수 있으므로 쓰기 지연이 동작하지 않고 persist()가 호출하는 즉시 INSERT SQL이 실행된다.

SEQUENCE 전략

데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트다. 이 전략은 PostagreSQL, DB2, H2에서만 사용할 수 있다.

 

IDENTITY와 SEQUENCE의 전략은 같지만 내부 동작 차이는 다음과 같다.

  • IDENEITY: 먼저 엔티티를 데이터베이스에 저장한 후에 식별자를 조회해서 엔티티의 식별자에 할당한다.
  • SEQUENCE: persist()를 호출할 떄 먼저 데이터베이스 시퀀스를 사용해서 식별자를 조회한다. 그리고 조회한 식별자를 엔티티에 할당한 후에 엔티티를 영속성 컨텍스트에 저장한다.  이후 트랜잭션을 커밋해서 플러시가 일어나면 엔티티를 데이터베이스에 저장한다.

TABLE 전략

Table 전략은 키 생성 전용 테이블을 하나 만들고 여기에 이름과 값으로 사용할 컬럼을 만들어 데이터베이스 시퀀스를 흉내내는 전략이다. 이 전략은 테이블을 사용하므로 모든 데이터베이스에 적용할 수 있다.

Auto 전략

데이터베이스의 종류도 많고 기본 키를 만드는 방법도 다양하다. Auto는 선택한 데이터베이스 방언에 따라 위의 3가지 중 하나를 자동으로 선택한다.

정리

  • 직접 할당: em.persist()를 호출하기 전에 애플리케이션에서 직접 식별자 값을 할당해야 한다. 만약 식별자 값이 없으면 예외가 발생한다.
  • SEQUENCE: 데이터베이스 시퀀스에서 식별자 값을 획득한 후 영속성 컨텍스트에 저장한다.
  • TABLE: 데이터베이스 시퀀스 생성용 테이블에서 식별자 값을 획득한 후 영속성 컨텍스트에 저장한다.
  • IDENTITY: 데이터베이스에 엔티티를 저장해서 식별자 값을 획득한 후 영속성 컨텍스트에 저장한다.

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

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

@Column

@Column은 객체 필드를 테이블 컬럼에 매핑한다.

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

@Enumerated

자바의 enum 타입을 매핑할 때 사용한다.

속성 기능 기본값
value EnumType.ORDINAL: enum 순서를 DB에 저장
EnumType.STRING: enum 이름을 DB에 저장
EnumType.ORDINAL
  • EnumType.ORDINAL
    • 장점: 데이터베이스에 저장되는 데이터 크기가 작다.
    • 단점: 이미 저장된 enum의 순서를 변경할 수 없다.
  • EnumType.STRING(권장)
    • 장점: 저장된 enum의 순서가 바뀌거나 enum이 추가되어도 안전하다.
    • 단점: 데이터베이스에 저장되는 데이터 크기가 ORDINAL에 비해서 크다.

@Termporal

날짜 타입을 매핑할 때 사용한다.

속성 기능 기본값
value TemporalType.DATE: 날짜, DB date 타입과 매핑
TemporalType.TIME: 시간, DB time 타입과 매핑
TemporalType.TIMESTAMP: 날짜 시간, DB의 timestamp 타입과 매핑
TEMPORALType은 필수로 지정해야한다.
  • datetime: MySQL
  • timestamp: H2, 오라클, PostgreSQL

@Access

JPA가 엔티티 데이터에 접근하는 방식을 지정한다.

  • 필드 접근: AccessType.FIELD로 지정한다. 필드에 직접 접근한다. 필드 접근 권한이 private이어도 접근할 수 있다.
  • 프로퍼티 접근: AccessType.PROPERTY로 지정한다. 접근자를 사용한다.