3. 엔티티 매핑

1. 객체와 테이블 매핑

1) @Entity

  • @Entity가 붙은 클래스는 JPA가 관리
  • 기본 생성자 필수
  • final 클래스, enum, interface, inner 클래스 사용 x
  • 저장할 필드에 final 사용 x
package hellojpa;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
//@Table(name = "user") >> 다른 이름의 테이블과 매핑
public class Member {

    @Id
    private Long id;
    private String name;

    public Member() {
    }

    public Member(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

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

  • 애플리케이션 로딩 시점에 DB 테이블 생성 기능 제공
  • 각기 다른 데이터베이스에 따라 적절한 테이블 생성
  • 이렇게 생성된 DDL은 개발 장비에서만 사용
  • property name="hibernate.hbm2ddl.auto" value="create" 추가
    • create-drop: 애플리케이션 종료 시점에 테이블 종료
    • update: 변경 부분만 반영, 변경 사항이 생기면 drop 하지 않고 alter로 실행, 지우는 것은 불가 추가만 가능
    • validate: 엔티티와 테이블이 정상 매핑됬는지 알려줌
    • none: 사용하지 않음
  • 기존 테이블을 지우고 테이블을 새로 생성
    -> 개발 중에 테이블 변경이 필요할 때 일일히 create을 할 필요가 없어짐
  • 운영 장비에서는 절대 create, create-drop, update를 사용하면 안된다
    • 개발 초기에는 create, update
    • 테스트 서버는 update, validate
    • 스테이징과 운영 서버는 validate, none

3) 필드와 컬럼 매핑

@Entity
public class Member {
    @Id
    private Long id;

    @Column(name = "name") >> 컬럼 명 지정
    private String username;

    private Integer age;

    @Enumerated(EnumType.STRING) >> enum 타입 
    private RoleType roleType;

    @Temporal(TemporalType.TIMESTAMP) >> 날짜 타입 date, time, timestamp
    private Date createdDate;

    @Temporal(TemporalType.TIMESTAMP)
    private Date lastModifiedDate;

    @Lob >> 큰 컨텐츠 
    private String description;

	@Transient >> db와 매핑하지 않음, 메모리에서만 사용
	private int temp;
    public Member() {
    }
}
  • @Columns
    • insertable, updatable: 등록 변경 가능 여부
    • nullable: false로 하면 not null 제약 조건 생성
    • unique: 컬럼에서 사용하면 이름이 불분명하여 @Table에서 사용
    • length: 문자 길이 제약 조건
    • columnDefinition: 데이터베이스 컬럼 정보를 직접 줄 수 있다.
    • precision, scale: 소숫점, 자릿수(BigDecimal)
  • enum 타입의 주의 사항
    • default 값 ordinal: enum의 순서를 데이터베이스에 저장
      -> 운영 상에 문제가 생길 수 있다
    • String: enum의 이름을 데이터베이스에 저장
  • @Temporal
    • 날짜 타입을 매핑할 때 사용
    • LocalDate, LocalDateTime을 사용할 때는 생략 가능

4) 기본 키 매핑

  • 직접 할당: @Id
  • 자동 생성: @GeneratedValue
    • (strategy = GenerationType.AUTO): DB 방언에 맞춰서 알아서 생김
    • (strategy = GenerationType.Identity): 기본키 생성을 DB에 위임
      • EX) mysql의 auto_increment
        • 기본 제약 조건이 있는 table을 미리 생성해놓아야 한다.
        • 데이터 베이스에 insert를 해야 id값을 알 수 있다.
          -> 그렇기 때문에 em.persist()를 실행하자 마자 insert 쿼리가 실행된다.
    • (strategy = GenerationType.Sequence): 시퀀스 오브젝트를 통해 값을 주입
      • 테이블마다 시퀀스를 따로 관리하고 싶으면 @SequenceGenerator 사용
        • insert를 하기 전에 sequence 값을 먼저 가져온다.
    • (strategy = GenerationType.Table): 키 생성 전용 테이블을 하나 만들어서 데이터 베이스 시퀀스를 흉내
      • 장점: 모든 데이터베이스 적용 가능
        • 단점: 성능이 떨어진다.
  • 권장하는 시퀀스 전략
    • 기본키 제약조건: null이 아님, 유일, 변하면 안된다.
    • 미래까지 위 조건을 만족하는 자연키는 없기 때문에 대리키를 사용
      - EX) 주민등록번호 X -> index 대리키로 사용
      - 권장 Long + 대체키 + 키 생성 전략 사용(Auto_increment or Sequence)
  • 데이터 중심 설계의 문제점
    • 현재 방식은 객체 설계를 테이블 설계에 맞춘 방식
    • 테이블의 외래키를 참조
    • Order 테이블이 member_id를 가지고 있는 것
      -> 연관관계 매핑으로 해결

좋은 웹페이지 즐겨찾기