Chapter4. Entity Mapping

김신영·2022년 11월 16일
0

JPA

목록 보기
2/14
post-thumbnail
post-custom-banner

JPA Annotations

1. 객체와 테이블 매핑

- `@Entity`
- `@Table`

2. PK 매핑

  • @Id
  • @GeneratedValue(strategy = GenerationType.IDENTITY)
    - GenerationType.AUTO
    - GenerationType.IDENTITY
    - GenerationType.SEQUENCE
    - GenerationType.TABLE
  • @SequenceGenerator
  • @TableGenerator

3. 필드와 컬럼 매핑

  • @Column

4. 연관관계 매핑

  • @JoinColumn
  • @ManyToOne
  • @OneToMany(mappedBy = "")
  • @OneToOne
  • @ManyToMany
  • @JoinTable

@Entity

JPA를 사용해서 테이블과 매핑할 클래스, Entity

속성기능기본값
nameEntity 이름this.class.getSimpleName()

@Entity 적용 시 주의사항

  • 기본 생성자는 필수다. (public, protected 기본 생성자)
  • final class, enum class, interface, inner class 에는 적용할 수 없다.
  • 저장할 필드에 final을 사용하면 안 된다.

JPA가 엔티티 객체를 생성할 때 기본 생성자를 사용한다.

@Table

엔티티와 매핑할 테이블을 지정한다.

속성기능기본값
name매핑할 Table 이름@Entity.name
catalogcatalog를 매핑한다.
schemaschema를 매핑한다.
uniqueConstraints (DDL)DDL 자동 생성 시, unique constraints를 만든다.
@Entity
@Table(
	name = "MEMBER", 
	uniqueConstraints = {
		@UniqueConstraint(
			name = "UNIQUE_GROUP_TEAM", 
			columnNames = {"groupId", "teamId"}
		)
	}
)
public class Member {
	// ...
}

META-INF/persistence.xml

<?xml version="1.0" encoding="UTF-8"?>  
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">  
    <persistence-unit name="unit-name">  
        <properties>  
            <!-- 필수 속성 -->  
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>  
            <property name="javax.persistence.jdbc.user" value="sa"/>  
            <property name="javax.persistence.jdbc.password" value=""/>  
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:~/Workspace/h2-test/test"/>  
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />  
  
            <!-- 옵션 -->  
            <property name="hibernate.hbm2ddl.auto" value="create"/>  
            <property name="hibernate.show_sql" value="true" />  
            <property name="hibernate.format_sql" value="true" />  
            <property name="hibernate.use_sql_comments" value="true" />  
            <property name="hibernate.id.new_generator_mappings" value="true" />  
  
            <property name="hibernate.hbm2ddl.auto" value="create" /> 
        </properties>  
    </persistence-unit>  
</persistence>

DDL 자동 생성 기능 설정

<property name="hibernate.hbm2ddl.auto" value="create" /> 
옵션설명
createDROP + CREATE
create-dropDROP + CREATE + DROP
update데이터베이스 테이블과 엔티티 매핑 정보를 비교해서 변경 사항만 수정한다.
validateDDL 수정하지 않는다. 유효성만 체크한다.
none자동생성 기능 미사용

이름 매핑 전략 변경 설정

카멜 표기법에서 언더 스코어 표기법으로 자동 변경해줌

<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy" /> 

@Id

객체 필드와 테이블의 기본키 매핑

기본 키 생성 전략

  1. 기본 키 직접 할당
  2. GenerationType.IDENTITY
  3. GenerationType.SEQUENCE
  4. GenerationType.TABLE
  5. GenerationType.AUTO

1. 기본 키 직접 할당 전략

@Entity
@Table(name = "MEMBER")
@NoArgsConstructor
@Setter
@Getter
class Member {
	@Id
	private Long id;
}

Member member = new Member();
member.setId(1001L);
em.persist(member);

2. IDENTITY 전략

기본 키 생성을 데이터베이스에 위임하는 전략이다.

주로 MySQL, PostgreSQL, SQL Server, DB2에서 사용한다.

  • IDENETITY 전략은 엔티티를 데이터베이스에 저장해야 PK를 구할 수 있으므로, em.persist()를 호출하는 즉시 INSERT SQL이 데이터베이스에 전달된다.
  • IDENTITY 전략은 쓰기지연이 동작하지 않는다.
@Entity
@Table(name = "MEMBER")
@NoArgsConstructor
@Setter
@Getter
public class Member {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
}

3. SEQUENCE 전략

Sequence는 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트이다.

@Entity
@Table(name = "MEMBER")
@SequenceGenerator(
	name = "BOARD_SEQ_GENERATOR",
	sequenceName = "BOARD_SEQ",
	initialValue = 1, allocationSize = 1
)
@NoArgsConstructor
@Setter
@Getter
public class Member {
	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "BOARD_SEQ_GENERATOR")
	private Long id;
}
속성기능기본값
nameSequenceGenerator 이름필수값
sequenceName데이터베이스 Sequence 이름hibernate_sequence
initialValueDDL 생성 시에만 사용됨.1
allocationSizeSequence 한 번 호출에 증가하는 수(성능 최적화에 사용됨)50
catalog, schema데이터베이스 catalog, schema 이름
  • 매핑되는 DDL은 다음과 같다.
CREATE SEQUENCE ${sequenceName}
START WITH ${initialValue} INCREMENT BY ${allocationSize};

SELECT ${sequenceName}.NEXTVAL FROM DUAL;

4. TABLE 전략

키 생성 전용 테이블을 하나 만들고 여기에 이름과 값으로 사용할 컬럼을 만들어 데이터베이스 sequence를 흉내내는 전략이다.

CREATE TABLE TABLE_SEQUENCES (
	SEQUENCE_NAME VARCHAR(255) NOT NULL,
	NEXT_VAL BIGINT
)

ALTER TABLE TABLE_SEQUENCES
ADD CONSTRAINT PK_TABLE_SEQUENCES PRIMARY KEY (SEQUENCE_NAME)
@Entity
@Table(name = "MEMBER")
@TableGenerator(
	name = "BOARD_SEQ_GENERATOR",
	table = "TABLE_SEQUENCES",
	pkColumnValue = "MEMBER_SEQ",
	allocationSize = 1
)
@NoArgsConstructor
@Setter
@Getter
public class Member {
	@Id
	@GeneratedValue(strategy = GenerationType.TABLE, generator = "BOARD_SEQ_GENERATOR")
	private Long id;
}
속성기능기본값
nameTableGenerator 이름필수값
table키생성 테이블 이름hibernate_sequences
pkColumnNameSeqeunce 컬럼명sequence_name
valueColumnNameSequence 값 컬럼명next_val
pkColumnValue키로 사용할 값 이름엔티티 이름
initialValue초기 값. 마지막으로 생성된 값0
allocationSizeSequence 한 번 호출에 증가하는 수(성능 최적화에 사용됨)50
catalog, schema데이터베이스 catalog, schema 이름
uniqueConstraints (DDL)유니크 제약 조건을 지정할 수 있다.

5. AUTO 전략

데이터베이스 Dialect에 따라 IDENTITY, SEQUENCE, TABLE전략 중 하나를 자동으로 선택한다.

  • @GeneratedValue.strategy의 기본 값은 AUTO
@Entity
@Table(name = "MEMBER")
@NoArgsConstructor
@Setter
@Getter
public class Member {
	@Id
	@GeneratedValue
	private Long id;
}
  • @OneToMany(mappedBy = "")
  • @OneToOne
  • @ManyToMany
  • @JoinTable

@Column

객체 필드와 테이블 컬럼 매핑

  • @Column
  • @Enumerated
  • @Temporal (LocalDate, LocalDateTime)
  • @Lob
  • @Transient
속성기능기본값
name필드와 매핑할 테이블의 컬럼 이름객체의 필드 이름
insertable엔티티 저장시 이 필드도 같이 저장true
updatable엔티티 수정 시 이 필드도 같이 수정true
table필드와 매핑할 컬럼이 속한 테이블현재 클래스가 매핑된 테이블
nullable (DDL)true
unique (DDL)한 컬럼에 간단히 유니크 제약조건
columnDefinition (DDL)매핑할 데이터베이스 컬럼 정보
length (DDL)문자 길이 제약조건, String 타입에만 사용255
precision, scale (DDL)precision은 소수점 포함 전체 자릿수, scale은 소수의 자릿수precision=19, scale=2
  • 생략해줘도 기본값으로 세팅된다.

@Enumerated

@Enumerated(value = EnumType.STRING)
  • @EnumType.ORDINAL (사용 권장하지 않는다.)
  • @EnumType.STRING

@Transient

해당 필드를 매핑하지 않는다.

profile
Hello velog!
post-custom-banner

0개의 댓글