JPA - 엔티티 매핑에 관련하여

Sungjin·2021년 7월 8일
0

JPA

목록 보기
4/10
post-thumbnail

객체와 테이블 Mapping

  • @Entity Annotation
    • @Entity가 붙은 클래스는 JPA가 관리, 데이터베이스의 테이블과 매핑 된다!
    • 기본 생성자 필수
    • final 클래스, enum, interfce, inner 클래스에는 사용할 수 없음
    • 저장할 필드에 final 사용 안됨
    • name 속성 : JPA에서 사용할 엔티티 이름 지정, 같은 클래스 이름이 없으면 가급적 기본 값 사용 권장
    //default 로는 기존 클래스의 이름을 그대로 사용한다.
    @Entity(name="Member")
  • @Table Annotation
    엔티티와 매핑할 테이블 지정
    • 속성
      • name : 매핑할 테이블 이름 . 기본 값으로 엔티티 이름을 사용
      • catalog : 데이터베이스 catalog 매핑
      • schema : 데이터베이스 schema 매핑
      • uniqueConstraints : DDL 생성 시에 유니크 제약 조건 생성.

ex)

@Entity
@Table(name="ORDERS")
public class Order  {
	
    //Data Filed

}

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

  • DDL 을 애플리케이션 실행 시점에 자동 생성

    여기서 DDL이란?
    Data Definition Language로서 스키마를 정의하거나, 수정 또는 삭제하기 위해 사용
    테이블을 생성하고 변경,제거하는 기능을 제공
    대표적으로 CREATE, DROP, ALTER문 등이 해당

  • 데이터 베이스에 맞는 방언을 활용해서 데이터베이스에 맞는 적절한 DDL 생성
  • 이렇게 생성된 DDL은 개발 장비에서만 사용
  • 생성된 DDL은 운영 서버에서는 일반적으로 사용 x
    ex)
  • 운영 장비에는 create, create-drop, update를 사용 하면 안됨!
    자칫 잘못하면 데이터가 다 날아갈 수 있음!
  • DDL을 자동 생성할 때만 사용되고 JPA의 실행 로직에는 영향을 주지 않음

필드와 컬럼 매핑

객체의 데이터 필드와 테이블의 컬럼을 매핑!
ex)

@Entity 
public class Member { 

 @Column(name = "name") 
 private String username; 
  
 @Enumerated(EnumType.STRING) 
 private Role role; 
 
 @Temporal(TemporalType.TIMESTAMP) 
 private Date createdAt; 
 
 @Lob 
 private String description; 

} 
  • 매핑 Annotation
    • @Column : 컬럼 매핑
      • 중요 속성
        • name : 필드와 매핑할 테이블의 컬럼 이름. 기본값으로는 객체의 필드 이름
        • insertable,updatable : 등록, 변경 가능 여부
        • nullable
        • unique
    • @Enumerated : 자바 enum 타입을 매핑할 때 사용
      • 중요 속성
        • EnumType.ORDINAL : enum 순서를 데이터 베이스에 저장
        • EnumType.String : enum 이름을 데이터베이스에 저장
      • 실무에서는 ORDINAL 속성을 사용하면 안됨!!!
        ORDINAL 속성을 사용하게 되면 enum 클래스에 데이터 필드의 추가,변경등으로 인해 순서가 혼란이 될 수 있음. 이는 전체 Application에 혼란을 가져다 줌.
    • @Temporal : 날짜 타입을 매핑할 때 사용
      • LocalDate, LocalDateTime을 사용할 때는 생략 가능
    • @Lob
      데이터베이스 BLOB,CLOB 타입과 매핑
      지정가능한 속성 없음
      • 매핑하는 필드 타입이 문자면 CLOB, 나머지는 BLOB으로 매핑하여 사용하면 됨
    • @Transient
      • 필드 매핑 하지 않음
      • 메모리 상에서만 임시로 저장하기 위해 사용

기본 키 매핑

필드에 기본 키를 매핑하기 위해 사용!
ex)

@Entity 
public class Member { 
	
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
}
  • @Id Annotation : 필드에 기본 키 Mapping

  • @GeneratedValue Annotation : 기본 키의 저장 방식을 정함

    • IDENTITY: 데이터베이스에 위임, MySQL

      • MySQL의 AUTO_INCREMENT 전략과 비슷
      • AUTO_ INCREMENT는 데이터베이스에 INSERT 문을 사용한 이후에 ID값을 알 수 있음
      • 즉, 제약이 생김.JPA의 커밋 시점 SQL 실행이 아닌 엔티티 매니저가 persist()시점에 즉시 INSERT문을 실행 하여 DB에서 식별자를 조회
    • SEQUENCE: 데이터베이스 시퀀스 오브젝트 사용, Oracle, @SequenceGenerator 필요
      - 중요 속성
      - sequenceName : 데이터베이스에 sequence로 등록할 이름
      - initialValue : 초기 Id에 할당 될 값
      - allocationSize: 데이터 베이스의 sequence값을 호출할 시에 증가하는 수
      ex) SEQUENCE

      @Entity 
      @SequenceGenerator( 
       name = “MEMBER_SEQ_GENERATOR", 
       sequenceName = “MEMBER_SEQ",
       initialValue = 1, allocationSize = 1) 
      public class Member { 
      
       @Id 
       @GeneratedValue(strategy = GenerationType.SEQUENCE, 
       generator = "MEMBER_SEQ_GENERATOR") 
       private Long id;
      }
    • TABLE: 키 생성용 테이블 사용, 모든 DB에서 사용 , @TableGenerator 필요
      - 모든 데이터 베이스에 적용 가능. But, 데이터베이스에 키 생성 전용 테이블을 하나 따로 만들어야 하기 때문에 성능이 좋지 못함!
      - 중요 속성
      - table : 키가 생성되어있는 테이블 명
      - pkColumnValue : 키로 사용할 값 이름
      - initailValue 와 allocationSize는 Sequence 전략과 같음
      ex) Table

      @Entity 
      @TableGenerator( 
       name = "MEMBER_SEQ_GENERATOR", 
       table = "MY_SEQUENCES", 
       pkColumnValue = “MEMBER_SEQ", allocationSize = 1) 
       //데이터 베이스에"MEmBER_SEQ"라는 값을 날리게 됨. 
      public class Member { 
       @Id 
       @GeneratedValue(strategy = GenerationType.TABLE, 
       generator = "MEMBER_SEQ_GENERATOR") 
       private Long id;
      }
    • AUTO: 자동 지정, 기본값!

  • SEQUENCE 전략 & TABLE 전략 성능 최적화 방법!
    sequence및 테이블의 Id 값을 데이터베이스와 통신을 하여 알아와야 함. 이 과정에서 성능이 저하 될 수 있음!
    allocationSize를 조정함으로서 성능을 최적화 시킬 수 있음.
    어떻게?
    allocationSize가 1로 설정 되었다고 가정. Entity를 영속성 컨텍스트에 persist 시킬 때 마다 Id 값을 가져와야 함! -> allocationSize를 그럼 50으로 늘려 보자!
    allocationSize가 50으로 늘어나게 되면 데이터베이스 상에서 sequence 및 table의 호출이 일어날 때마다 50씩 사이즈가 증가하게됨.
    이는 우리 Application에서 sequence를 한번에 당겨서 50개를 읽어오게 되는 이유.
    그러니, persist가 50개가 될 때 까지는 Id값을 위해 데이터베이스와 별도의 통신을 하지 않아도 됨!
    그렇다면 allocationSize를 엄청 크게 ??
    물론 더 많이 Id값을 당겨 오므로 좋을 수 있음.
    하지만! Id값이 당겨 와진 상태로 서버가 다운이 된다면 메모리에 저장된 값을 다 날림. 즉, 나머지 만큼의 Id값을 잃어 버릴 수 있음.
    적당히 크게 설정합시다~

이상으로 포스팅을 마치겠습니다. 감사합니다 :)

이 글은 인프런 김영한님의 '자바 ORM 표준 JPA 프로그래밍 - 기본편'을 수강하고 작성합니다.
출처:https://www.inflearn.com/course/ORM-JPA-Basic

profile
WEB STUDY & etc.. HELLO!

0개의 댓글