[JPA] 03. 엔티티 매핑

joheera·2023년 7월 11일
0

JPA

목록 보기
3/9

객체와 테이블 매핑

@Entity

@Entity가 붙은 클래스는 JPA가 관리한다. JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수이다. Entity 클래스는 기본 생성자가 필수이다.

@Entity 속성

name : JPA에서 사용할 엔티티 이름을 지정한다. 기본값은 클래스 이름을 그대로 사용한다. 중복되는 클래스 이름이 있는 경우가 아니라면 가급적 기본 값을 사용한다.

@Table

@Table은 Entity와 매핑할 테이블을 지정한다.

데이터베이스 스키마 자동 생성

JPA에서는 별도로 DDL을 생성하지 않아도 애플리케이션 실행 시점에 DDL을 자동 생성해준다. 자동 생성된 DDL은 불완전할 수 있기 때문에 운영서버가 아닌 개발 장비에서만 사용하는 것이 좋다.

hibernate.hbm2ddl.auto 속성

create : 기존 테이블 삭제 후 다시 생성(DROP + CREATE)
create-drop : create와 같으나 종료시점에 테이블 DROP
update : 변경분만 반영(운영DB에는 사용하면 안됨)
validate : 엔티티와 테이블이 정상 매핑되었는지만 확인

주의할 점

운영 장비에는 절대 create, create-drop, update를 사용하면 안된다. 로컬 PC가 아닌 개발 서버에서도 가급적 사용하지 않는 것을 권장한다.

DDL 생성 기능

JPA에서는 @Column(nullable = false, length = 10)과 같이 제약조건을 추가할 수 있다. 추가한 제약조건은 DDL 자동 생성에 반영된다. DDL 생성 기능은 DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다.

필드와 컬럼 매핑

매핑 어노테이션 정리

@Column

속성설명
insertable & updatable등록, 변경 가능 여부를 지정한다. 기본값은 TRUE이다.
nullable(DDL)null값의 허용 여부를 설정한다. false로 설정하면 DDL 생성 시에 not null 제약 조건이 붙는다.
unique(DDL)DDL문을 생성할 때 정확한 이름으로 unique 조건이 생성되지 않기 때문에 @TableuniqueConstaints을 사용한다.
columnDefinition(DDL)데이터베이스 컬럼 정보를 직접 줄 수 있다. ex) varchar(100) default 'EMPTY'
length(DDL)문자 길이 제약조건, String 타입에만 사용한다.
precision & scale(DDL)BigDecimal 타입에서 사용한다(BigInteger에서도 사용 가능). precision은 소수점을 포함한 전체 자릿수를, scale은 소수의 자릿수이다.

@Enumerated

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

EnumType.ORDINAL : enum 순서를 데이터베이스에 저장, 기본값
EnumType.STRING : enum 이름을 데이터베이스에 저장
EnumType.ORDINAL 사용 시, 데이터 추가 등의 상황에 장애가 발생할 수 있기 때문에 주의해야 한다.

@Temporal

날짜 타입을 매핑할 때 사용한다. LocalDate, LocalDateTime을 사용할 때는 @Temporal 어노테이션 생략이 가능하다.

TemporalType.(DATE/TIME/TIMESTAMP) : 각각 date, time, timestamp에 매핑한다.

@Lob

데이터베이스 BLOB, CLOB 타입과 매핑한다. @Lob에는 지정할 수 있는 속성이 없다. 매핑하는 필드 타입이 문자면 CLOB, 나머지는 BLOB으로 자동으로 매핑해준다.

@Transient

컬럼에 매핑하고 싶지 않는 필드에 사용한다. @Transient를 사용한 필드는 데이터베이스에 저장되거나 조회되지 않는다. 주로 메모리 상에서만 임시로 어떤 값을 보관하고 싶을 때 사용한다.

기본 키 매핑

기본키를 매핑하는 방법에는 @ID을 사용하여 직접 할당하는 방법과 @GeneratedValue를 사용하여 자동 생성하는 방법이 있다.

GeneratedValue 전략

IDENTITY 전략

기본 키 생성을 데이터베이스에 위임한다(ex) MYSQL의 AUTO_INCREMENT). JPA는 보통 트랜잭션 커밋 시점에 한꺼번에 INSERT SQL을 실행한다. AUTO_INCREMENT는 데이터베이스에 INSERT SQL을 실행한 이후에 ID 값을 알 수 있기 때문에 트랜잭션 커밋 시점에 INSERT SQL을 실행하게 되면 영속성 컨텍스트에서 객체를 관리할 수 없다. 따라서 IDENTITY 전략에서는 em.persist() 시점에 즉시 INSERT SQL을 실행하고 DB에서 식별자를 조회해 온다.

SEQUENCE 전략

allocationSize : 시퀀스 한 번 호출에 증가하는 수(성능 최적화에 사용된다.) 기본 값은 50이며 동시성 문제를 해결할 수 있다.

TABLE 전략

키 생성 전용 테이블을 하나 만들어서 데이터베이스 시퀀스를 흉내내는 전략이다. 모든 데이터베이스에 적용이 가능하다는 장점이 있지만 성능적으로는 좋지 않다. 잘 사용되지는 않는다.

권장하는 식별자 전략

데이터베이스에서 기본 키 제약 조건은 null이 아니면서, 유일해야 하고, 불변한 값이여야 한다. 미래까지 이 조건을 만족하는 자연키는 찾기 어려우므로 대체키를 사용하는 것이 좋다. 예를 들어 주민등록번호 또한 기본 키로 적절하지 않다(비즈니스를 키로 끌고 오지 않음). 식별자에는 Long형을 사용하며, 대체키, 키 생성전략을 사용하는 것을 권장한다.

데이터 중심 설계의 문제점

  • 현재 방식은 객체 설계를 테이블 설계에 맞춘 방식
  • 테이블의 외래키를 객체에 그대로 가져옴
  • 객체 그래프 탐색이 불가능
  • 참조가 없으므로 UML도 잘못됨

0개의 댓글