[JPA 프로그래밍] 3. 엔티티 매핑

반응형
728x90
반응형

@Entity

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

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

JPA가 엔티티 객체를 생성할때 기본 생성자를 사용하므로 이 생성자는 반드시 있어야한다. 

 

 

@Table

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

 

 

다양한 매핑 사용

Member.java
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.Date;


@Entity
@Table(name="MEMBER", uniqueConstraints = {@UniqueConstraint(
        name = "NAME_AGE_UNIQUE",
        columnNames = {"NAME", "AGE"}
)})
@Getter
@Setter
public class Member {
    @Id
    @Column(name= "ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private String id;

    @Column(name = "NAME", nullable = false, length = 10)
    private String username;

    private Integer age;

    @Enumerated(EnumType.STRING)
    private RoleType roleType;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;

    @Lob // CLOB 타입 에 매핑
    private String description;

    @Transient
    private Integer temp;
}

 

RoleType.java
public enum RoleType {
    ADMIN, USER
}

 

1) enum 사용

enum 을 사용한 회원의 타입 구분
- 일반 회원 : USER
- 관리자 : ADMIN*

member.setRoleType(RoleType.ADMIN);
DB 에 문자열로 저장된다. -> ADMIN

EnumType.ORDINAL 은 0, 1로 정의 순서값이 저장되는데 이미 저장된 enum의 순서를 변경할 수가 없다.
STRING 으로 하는것이 안전하다.

@Enumerated(EnumType.STRING)
private RoleType roleType;

 

2) DATE

@Temporal 생략시 timestamp 로 default 설정된다.

  • TemporalType.DATE : 날짜 (date date)
  • TemporalType.TIME : 시간 (time time)
  • TemporalType.TIMESTAMP : 날짜와 시간 (timestamp timestamp)
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;

@Temporal(TemporalType.TIMESTAMP)
private Date lastModifiedDate;

 

3) CLOB, BLOB

  • CLOB : String, char[], java.sql.CLOB (문자일 경우)
  • BLOB : byte[], java.sql.BLOB (그 외)
@Lob // CLOB 타입 에 매핑
private String description;

 

4) @Transient

매핑하지 않는다. 객체에 임시로 어떤 값을 보관해야할 경우 사용한다.

@Transient
private Integer temp;

 

 

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

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

 

 

DDL 생성 기능

DDL 을 자동 생성할때만 사용되고 JPA 실행 로직에는 영향을 주지 않는다.
따라서 스키마 자동 생성 기능을 사용하지 않고 DDL 을 만든다면 사용할 이유가 없다.
하지만 이 코드를 보고 명시적으로 제약 조건을 파악할 수 있다.

@Table(name="MEMBER", uniqueConstraints = {@UniqueConstraint(
        name = "NAME_AGE_UNIQUE",
        columnNames = {"NAME", "AGE"}
)})

 

 

기본 키 매핑

기본키 자동생성 

옵션 설명
IDENTITY 기본 키 생성을 데이터베이스에 위임한다.
데이터베이스에 엔티티를 저장해서 식별자 값을 획득한 후 영속성 컨텍스트에 저장한다. 
SEQUENCE 데이터베이스 시퀀스를 사용해서 기본키를 할당한다.
데이터베이스 시퀀스에서 식별자 값을 획득한 후 영속성 컨텍스트에 저장한다.
TABLE 키 생성 테이블을 사용한다.
데이터베이스 시퀀스 생성용 테이블에서 식별자 값을 획득한 후 영속성 컨텍스트에 저장한다. 
AUTO @GeneratedValue.strategy의 기본값은 AUTO다. 
데이터베이스 방언(오라클, Mysql 등)에 따라 위 3가지 전략 중 하나를 자동으로 선택한다.

 

 

필드와 컬럼 매핑

분류 매핑 어노테이션 설명
필드와 컬럼 매핑 @Column 컬럼을 매핑한다.
@Enumerated 자바의 enum 타입을 매핑한다.
@Temporal 날짜 타입을 매핑한다.
@Lob BLOB, CLOB 타입을 매핑한다.
- CLOB : String, char[], java.sql.CLOB (문자일 경우)
- BLOB : byte[], java.sql.BLOB (그 외)
@Transient 특정 필드를 데이터 베이스에 매핑하지 않는다.
기타 @Access JPA가 엔티티에 접근하는 방식을 지정한다.

 

 

@Access

  • 필드 접근 : AccessType.FIELD로 지정한다. 필드에 직접 접근한다. 필드 접근 권한이 private이어도 접근할 수 있다.
  • 프로퍼티 접근 : AccessType.PROPERTY로 지정한다. 접근자(Getter)를 사용한다. 
@Entity
@Access(AccessType.FIELD)
public class Member {
    @Id
    private String id;
    
    ...
}

@Access를 설정하지 않으면 @Id의 위치를 기준으로 접근 방식이 설정된다. 

위 예제에서 @Id가 필드에 있으므로 @Access 설정은 @Access(AccessType.FIELD)로 설정한 것과 같다. 이때는 @Access는 생략해도 된다.

 

@Id가 프로퍼티에 있으므로 @Access(AccessType.PROPERTY)로 설정한 것과 같다. 

아래 예제는 getFullName()만 프로퍼티 접근 방식을 사용하여, 회원 엔티티를 저장하면 회원 테이블의 FULLNAME 컬럼에 firstName + flastName 결과가 저장된다.

@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;
    }
    
    ...
}

 

 

not null 설정

자바 기본 타입에는 null 값을 입력할 수 없다.
JPA 는 int type 은 not null 로 지정하는데, @Column 이 써지게되면 nullable=true 가 기본값이므로, 이럴땐 nullable=false 를 지정해주는게 좋다.

@Column(nullable = false)
private int cnt;

 

반응형

Designed by JB FACTORY