쿵쿵일지
엔티티 매핑 본문
엔티티 매핑
jpa를 사용하는데 가장 중요한 일은 엔티티와 테이블을 정확히 매핑하는 것
객체와 테이블 매핑 : @Entity, @Table
기본 키 매핑 : @Id
필드와 컬럼 매핑 : @Column
연관관계 매핑 : @ManyToOne, @JoinColumn
4.1 @Entity
JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션을 필수로 붙여야 한다.
속성
name : JPA에서 사용할 엔티티 이름을 지정, 설정하지 않으면 클래스 이름을 그대로 사용
주의사항 : 기본 생성자는 필수
final 클래스, enum, interface, inner 클래스에는 사용할 수 없다.
저장할 필드에 final을 사용하면 안 된다.
4.2 @Table
@Table은 엔티티와 매핑할 테이블을 지정한다. 생략하면 매핑한 엔티티 이름을 테이블 이름으로 사용한다.
속성
name : 매핑할 테이블 이름 ( 기본값으로 엔티티 이름을 사용한다.)
catalog : catalog 기능이 있는 데이터베이스에서 catalog를 매핑한다.
schema : schema 기능이 있는 데이터베이스에서 schema를 매핑한다.
uniqueConstraints : DDL 생성 시에 유니크 제약조건을 만든다. 이 기능은 스키마 자동 생성 기능을 사용해서 DDL을 만들 때만 사용된다.
4.3 다양한 매핑 사용
@Enumerated(EnumType.STRING)
@Temporal(TemporalType.TIMESTAMP)
@Lob
4.4 데이터베이스 스키마 자동 생성
JPA는 데이터베이스 스키마를 자동으로 생성하는 기능을 지원한다.
persistence.xml 에 <property name="hibernate.hbm2ddl.auto" value="create" />
옵션
create, create-drop, update, validate, none
이 속성을 추가하면 애플리케이션 실행 시점에 데이터베이스 테이블을 자동으로 생성
<property name="hibernate.show_sql" value="true" />
추가 하면 생성되는 테이블의 DDL을 출력할 수 있다.
여기서 꿀팁
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" /> 를 사용하면 보통 자바는 관례상 카멜 표기법으로 쓰지만
칼럼에 네임을 따로 지정해 주지 않아도 디비테이블은 언더스코어로 작성해 준다.
4.5 DDL 생성 기능
@Column의 length와 nullable 속성을 포함해서 이런 기능들은 단지 DDL을 자동으로 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않는다. 따라서 스키마 자동 생성 기능을 사용하지 않고 직접 DDL을 만든다면 사용할 이유가 없다.
4.6 기본 키 매핑
JPA가 제공하는 데이터베이스 기본 키 생성 전략은 다음과 같다.
직접 할당 : 기본 키를 애플리케이션에서 직접 할당한다.
자동 생성 : 대리 키 사용 방식
- IDENTITY : 기본 키 생성을 데이터 베이스에 위임 한다.
- SEQUENCE : 데이터베이스 시퀀스를 사용해서 기본 키를 할당한다.
- TABLE : 키 생성 테이블을 사용한다.
자동 생성 전략이 다양한 이유는 데이터베이스 벤더마다 지원하는 방식이 다르기 때문
기본 키를 직접 할당하려면 @Id만 사용하면 되고, 자동 생성 전략을 사용하려면 @Id에 @GeneratedValue를 추가하고 원하는 키 생성 전략을 선택하면 된다.
키 생성 전략을 사용하려면 persistence.xml에 <property name="hibernate.id.new_generator_mappings" value="true" /> 를 추가하여야 한다.
4.6.1 기본 키 직접 할당 전략
애플리케이션에서 기본 키를 직접 할당하는 방법
4.6.2 IDENTITY 전략
기본 키 생성을 데이터베이스에 위임하는 전략, 주로 MySQL, PostgreSQL, SQL server, DB2에서 사용한다.
이 전략을 사용하면 JPA는 기본 키 값을 얻어오기 위해 데이터베이스를 추가로 조회한다.
즉, INSERT 후 자동으로 생성된 ID값을 식별자에 값을 할당하기 위해 한번 더 디비를 조회해야 한다는 말.
JDBC3에 추가된 Statement.getGeneratedKeys()를 사용하면 데이터를 저장하면서 동시에 생성된 기본 키 값도 얻어 올 수 있다. 하이버네이트는 이 메소드를 사용해서 데이터베이스와 한 번만 통신한다. -> 이 부분을 코드로 직접확인해보자.
엔티티가 영속 상태가 되려면 식별자가 반드시 필요하다. 그런데 IDENTITY 식별자 생성 전략은 엔티티를 데이터베이스에 저장해야 식별자를 구할 수 있으므로 em.persist()를 호출하는 즉시 INSERT SQL이 데이터베이스에 전달된다. 따라서 이 전략은 트랜잭션을 지원하는 쓰기 지연이 동작하지 않는다.
4.6.3 SEQUENCE 전략
데이터베이스 시퀀스는 유일한 값을 순선대로 생성하는 특별한 데이터베이스 오브젝트
시퀀스를 지원하는 오라클, PostgreSQL, DB2, H2 데이터베이스에서 사용할 수 있다.
@SequnceGenerator 를 사용하여 BOARD_SEQ_GENERATOR라는 시퀀스를 등록
그 다음 generator로 등록하면 끝
시퀀스를 사용하면 em.persist()를 호출할 때 먼저 데이터베이스 시퀀스를 사용해서 식별자를 조회한다. 그리고 조회한 식별자를 엔티티에 할당한 후에 엔티티를 영속성 컨텍스트에 저장한다. 이후 트랜잭션을 커밋해서 플러시가 일어나면 엔티티를 데이터베이스에 저장한다.
allocationSize의 default값은 50인데 시퀀스 성능과 관련이 있다.
왜냐면 시퀀스 값을 50까지 선점해 놓고 1~50까지는 메모리에서 식별자를 할당한다. 그리고 51이 되면 시퀀스 값을 100으로 증가시킨 다음 51~100까지 메모리에서 식별자를 할당한다.
앞서 설명한 hibernate.id.new_generator_mappings 속성을 true로 설정해야 지금 까지 설명한 최적화 방법이 적용된다.
4.6.4 TABLE 전략
TABLE 전략은 키 생성 전용 테이블을 하나 만들고 여기에 이름과 값으로 사용할 칼럼을 만들어 데이터 베이스 시퀀스를 흉내내는 전략
4.6.5 AUTO 전략
데이터베이스 방언에 따라 IDENTITY, SEQUENCE, TABLE 전략 중 하나를 자동으로 선택한다. 예를 들어 오라클을 선택하면 SEQUENCE를, MYSQL을 선택하면 IDENTITY를 사용한다.
4.7 필드와 컬럼 매핑: 레퍼런스
4.7.1 @Column
속성
name : 필드와 매핑할 테이블의 컬럼 이름
insertable : 엔티티 저장 시 이 필드도 같이 저장한다. false로 설정하면 이 필드는 데이터베이스에 저장하지 않는다.
updatable : 엔티티 수정 시 이 필드도 같이 수정한다. false로 설정하면 데이터베이스에 수정하지 않는다.
insertable, updatable은 읽기 전용일 때 사용한다. 이말이 뭐지?
table : 하나의 엔티티를 두 개 이상의 테이블에 매핑할 때 사용한다.
nulable : null 값의 허용 여부
unique : @Table의 uniqueConstraints와 같지만 한 칼럼에 간단히 유니크 제약조건을 걸 때 사용한다.
columnDefinition : 데이터베이스 칼럼 정보를 직접 줄 수 있다.
length : 문자 길이 제약조건, String 타입에만 사용한다.
prescision, scale : BigDecimal 타입에서 사용한다. precision은 소수점을 포함한 전체 자릿수를, scale은 소수의 자릿수다.
4.7.2 @Enumerated
EnumType.ORDINAL : enum 순서를 데이터베이스에 저장 -> enum의 순서가 바뀌게 되면 문제 발생 -> 확장성이 제한된다.
EnumType.STRING : enum 이름을 데이터베이스에 저장 -> 권장함
4.7.3 @Temporal
날짜 타입을 매핑할 때 사용한다.
TemporalType.DATE : 날짜, 데이터베이스 date 타입과 매핑
TemporalType.TIME : 시간, 데이터베이스 time 타입과 매핑
TemporalType.TIMESTAMP : 날짜와 시간, 데이터베이스 timestamp 타입과 매핑
timestamp 대신에 datetime을 예약어로 사용하는 데이터베이스도 있는데 데이터베이스 방언 덕분에 애플리케이션 코드는 변경하지 않아도 된다.
datetime : MySQL
timestamp: H2, 오라클, PostreSQL
4.7.4 @Lob
데이터베이스 BLOB, CLOB 타입과 매핑한다.
@Lob에는 지정할 수 있는 속성이 없다. 대신에 매핑하는 필드 타입이 문자면 CLOB으로 매핑하고 나머지는 BLOB으로 매핑한다.
4.7.5 @Transient
이 필드는 매핑하지 않는다. 따라서 데이터베이스에 저장하지 않고 조회하지도 않는다. 객체에 임시로 어떤 값을 보관하고 싶을 때 사용한다.
4.7.6 @Access
JPA가 엔티티 데이터에 접근하는 방식을 지정한다.
필드 접근 : AccessType.FIELD로 지정한다. 필드에 직접 접근한다. 필드 접근 권한이 private이어도 접근할 수 있다.
프로퍼티 접근 : AccessType.PROPERTY로 지정한다. 접근자를 사용한다.
'java > JPA' 카테고리의 다른 글
값 타입 (0) | 2016.06.01 |
---|---|
프록시와 연관관계 관리 (0) | 2016.05.25 |
다양한 연관관계 매핑 (0) | 2016.05.07 |
연관관계 매핑 기초 (0) | 2016.05.06 |
영속성 관리 (0) | 2016.04.13 |