Ep3. 엔티티 매핑

yumyeonghan·2023년 2월 3일
0

JPA

목록 보기
3/10

🍃이 글은 inflearn에서 김영한의 스프링 부트와 JPA 실무 완전 정복 로드맵을 학습하고 작성한 것입니다.🍃

객체와 테이블 매핑

  • @Entity

    • @Entity가 붙은 클래스는 엔티티라 하고, JPA가 관리한다.

    • JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수이다.

    • 주의

      • 기본 생성자 필수(파라미터가 없는 public 또는 protected 생성자)

      • final 클래스, enum, interface, inner 클래스는 @Entity를 사용 못 한다.

      • 저장할 필드에 final 사용 안 된다.

  • @Table

    • 엔티티와 매핑할 테이블 지정한다.
    • 유니크 제약조건을 @Column이 아닌 이름을 지정할 수 있는 @Table에서 하자.
    • @Table(uniqueConstraints = {@UniqueConstraint( name = "NAME_AGE_UNIQUE", columnNames = {"NAME", "AGE"} )})

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

  • 운영 장비에는 절대 create, create-drop, update 사용하면 안 된다.

  • 데이터베이스 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성한다.

  • 생성된 DDL은 개발 장비에서만 사용한다.

  • 운영 서버에서는 생성된 DDL을 적절히 수정한 후 사용한다.

DDL 생성 기능

  • 컬럼 제약조건 추가
    @Column(nullable = false, length = 10)
    • nullable = false : not null 제약조건 추가
    • length = 10 : 10자 초과x, 크기 제약조건 추가
  • 테이블 제약조건 추가

    @Table(name="MEMBER", uniqueConstraints = {@UniqueConstraint(name = "NAME_AGE_UNIQUE",columnNames = {"NAME", "AGE"} )})
    • Name, AGE 컬럼에 유니크 제약조건 추가
  • 이런 기능들은 단지 DDL을 자동으로 생성할 때만 사용되고 JPA 실행 로직에는 영향을 주지 않는다.

  • 스키마 자동 생성 기능을 사용하지 않고 직접 DDL을 만든다면 사용할 이유가 없다.

필드와 컬럼 매핑

  • 요구사항 추가

      1. 회원은 일반 회원과 관리자로 구분해야 한다.
      1. 회원 가입일과 수정일이 있어야 한다.
      1. 회원을 설명할 수 있는 필드가 있어야 한다.
    @Entity
    public class Member {
    
    @Id
    private Long id;
    
    @Column(name = "name")
    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
    private String description;
    
    @Transient
    private Integer temp;
    
    }
  • @Column

    • unique 속성

      • @Table의 uniqueConstraints와 같지만 이름을 지정할 수 없어 사용하기에는 무리가 있다.
  • @Enumerated

    • 자바 enum 타입을 매핑할 때 사용한다.
    • ORDINAL 사용하면 enum타입에 값을 추가할 때 기존 DB값의 순서가 꼬이는 위험이 있다.
    • STRING으로 사용하자.
  • @Temporal

    • 날짜 타입(Date, Calendar)을 매핑할 때 사용한다.
    • JAVA 8 이상부터 사용하는 LocalDate, LocalDateTime을 사용할 때는 생략 가능하다.
  • @Lob

    • 속성이 없다.
    • 매핑하는 필드 타입이 문자면 CLOB, 나머지는 BLOB 매핑한다.
  • @Transient

    • 필드와 컬럼을 매핑하지 않는다.
    • 데이터베이스에 저장, 조회 등을 하지 않는다.
    • 메모리상에서만 값을 보관하고 싶을 때 사용한다.

기본 키 매핑

@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
  • @Id: 기본 키를 직접 만들어서 할당할 때 @Id만 사용한다.
  • @GeneratedValue: 기본 키를 자동으로 생성해줄 때 @Id와 같이 사용한다.

보통 관계형 DB를 사용할 때 DB가 자동으로 숫자 값을 생성해주는 방식을 사용한다.

@GeneratedValue

  • IDENTITY

    • 기본 키 생성을 데이터베이스에 위임한다.

    • 주로 MySQL의 AUTO_ INCREMENT에서 사용한다.

    • 기본 키 값이 DB에 INSERT 쿼리가 반영될 때 적용된다.

    • IDENTITY 전략만 em.persist() 시점에 즉시 INSERT 쿼리가 반영되면서 JPA 내부적으로 DB에서 기본 키 값을 조회해 1차 캐시에 저장한다.(1차 캐시는 기본 키 값과 엔티티로 이루어져야 한다.)

      • 즉, 쓰기(저장, 수정, 삭제) 지연의 이점을 누릴 수 없다.
  • SEQUENCE

    • 주로 오라클 시퀀스에서 사용한다.

    • em.persist() 시점에 시퀀스 전략이면 기본 키 값을 DB에서 가져온 다음 엔티티에 적용하고 1차 캐시에 저장한다.

    • INSERT 쿼리는 트랜잭션 커밋 시점에 반영된다.

    • 엔티티를 em.persist()할 때마다 DB에서 기본 키 값을 가져오게 되면 성능상 문제가 생길 수 있다.

    • allocationSize 속성을 활용해서 크기를 지정하고, 메모리에서 1씩 사용해서 성능 최적화를 할 수 있다.

  • TABLE

    • 키 생성 전용 테이블을 만들어서 데이터베이스 시퀀스를 흉내내는 전략이다.

    • 성능이 떨어진다.

  • AUTO

    • 방언에 따라 자동 지정된다.

    • 기본값이다.

권장하는 식별자 전략

  • 데이터베이스 기본 키 제약조건

    • null이면 안 된다.

    • 유일해야 한다.

    • 변하면 안 된다.

  • 자연 키 대신 대체 키를 사용하자

    • 자연 키: 비즈니스적으로 의미 있는 키 - 주민등록번호, 전화번호

    • 대체 키: 비즈니스적으로 의미 없는 키 - 시퀀스, UUID

  • 권장: Long 형 + 대체 키 + 키 생성 전략 사용

profile
웹 개발에 관심 있습니다.

0개의 댓글