[JPA] 엔티티 매핑

왈왈왈 (Yoon tae uk)·2022년 5월 1일
1

엔티티 매핑

JPA에서의 엔티티 매핑에대해 알아봅니다.


Goal

  • 객체와 테이블 매핑
  • 스키마 자동 생성
  • 필드와 컬럼 매핑
  • 기본 키 매핑

엔티티 매핑

엔티티 매핑이란 객체와 테이블 사이의 관계나 속성을 지정할 수 있도록 매핑하는 것입니다.

  • 객체와 테이블 매핑: @Entity, @Table
  • 필드와 컬럼 매핑: @Column
  • 기본 키 매핑: @Id
  • 연관관계 매핑: @ManyToOne, JoinColumn

객체와 테이블 매핑

@Entity

JPA가 관리하는 클래스입니다.

JPA를 사용하여 테이블과 매핑할 클래스는 @Entity가 반드시 필요합니다.

속성: name

  • JPA에서 사용할 엔티티 이름을 지정합니다.
  • 기본값으로는 클래스 이름을 그대로 사용합니다.
  • 다른 클래스에 동일한 값이 존재하면 충돌이 발생합니다.

주의사항

  • 기본 생성자가 필수입니다. (public 또는 protect 생성자) JPA에서 제공하는 다양한 기능을 사용하기 위하여서입니다.
  • final, enum, interface, inner 클래스에는 사용할 수 없습니다. JPA에서는 지연 로딩을 사용할 때 프록시를 사용하는데 프록시를 사용할 때 해당 클래스를 상속받지 못하기 때문입니다.
  • 저장할 필드에 final 사용이 불가능합니다.

@Table

엔티티와 매핑할 테이블을 정합니다.

속성

  • name : 매핑할 테이블의 이름을 설정합니다, 기본값으로는 엔티티의 이름을 사용합니다.
  • catalog : 데이터베이스에서 catalog를 매핑합니다.
  • schema : 데이터베이스에서 schema를 매핑합니다.
  • uniqueConstraints(DDL) : DDL 생성 시에 유니크 제약조건을 생성합니다. ▻ 스키마 자동 생성을 사용하여 DDL을 생성 할 때만 사용합니다.

uniqueConstraints 속성

@Entity
@Table(name = "MEMBER", uniqueConstraints = @UniqueConstraint(
   name = "제약조건의 별칭",
   columnNames = {"ADDRESS", "NAME"} // 대상지정
))
@Getter
@NoArgsConstructor(access =AccessLevel.PROTECTED)
public class Member {
   ...
}

참고 @Entity와 @Table의 차이는?

@Entity(name = “”)는 말 그대로 엔티티의 이름을 정할때 사용합니다.

@Table(name = “”)는 데이터베이스에 생성될 테이블의 이름을 지정할 때 사용합니다.

만약 테이블이 없고 엔티티만 존재하면 엔티티에 의해서 테이블과 엔티티의 이름이 결정됩니다.


Id

@Id는 기본키 매핑에 사용합니다.

@Id 어노테이션을 사용하여 기본키를 직접 할당 할 수 있고, 데이터베이스가 값을 생성하여 사용할 수 도 있습니다.

직접 할당

  • 기본키를 직접 매핑하는 방법은 @Id 어노테이션만 매핑하면 됩니다.
  • 엔티티를 em.persist()로 저장하기전에 id값을 애플리케이션에서 기본키를 직접 할당합니다.
@Id
private Long id;

Member member1 = new Member();
member1.setId(1);
em.persist(member1);

자동 생성

  1. IDENTITY 전략
    • 기본키 생성을 데이터베이스에 위임합니다.
    • IDENTITY의 식별자 전략은 엔티티를 데이터베이스에 저장해야 식별자를 구할 수 있으므로 em.persist() 시점에 쓰기 지연을 사용하지 않습니다.
    • 주로 MySQL, PostgreSQL등 에서 사용합니다.
@Entity
@Getter
@NoArgsConstructor(access =AccessLevel.PROTECTED)
public class Member {

   @Id
   @GeneratedValue(strategy =GenerationType.IDENTITY)
   private Long id;

}
  1. SEQUNCE 전략
    • 유일한 값을 순서대로 생성하는 특별한 데이터베이스 오브젝트입니다.
    • 시퀀스를 이용하여 기본키를 생성합니다.
    • SEQUENCE 전략 역시 엔티티를 데이터베이스에 저장해야 식별자를 알 수 있습니다.
    • em.persist()시점에 시퀀스를 조회하는 쿼리를 데이터베이스에 날려 식별자를 조회한 후 엔티티에 할당합니다.

참고

시퀀스란 순차적으로 증가하는 데이터를 자동으로 반환하는 데이터베이스 객체를 말합니다.

@Entity
@SequenceGenerator(name = "MEMBER_SEQ_GENERATOR", //GenerateValue에서 사용하는 이름
                     sequenceName = "MEMBER_SEQ_ID", //데이터베이스에 등록된 이름
               initialValue = 1, 
               allocationSize = 1)
@Getter
@NoArgsConstructor(access =AccessLevel.PROTECTED)
public class Member {

  @Id   
	@GeneratedValue(strategy =GenerationType.SEQUENCE,
                        generator = "MEMBER_SEQ_GENERATOR")
	private Long id;
}

@SequenceGenerator 속성 정리

  • name : 식별자 생성기 이름
  • sequenceName : 데이트베이스에 등록된 시퀀스 이름
  • initialValue : DDL 사용시에만 사용합니다, 시퀀스 DDL을 생성할 때 초기 시작값을 의미합니다.
  • allocationSize : 시퀀스 호출에 증가하는 수(성능 최적화에 사용)
  • catalog, schema : 데이터베이스 catalog, schema 이름

allocationSize 주의점

allocationSize의 기본값은 50입니다, 값을 바꾸지 않는다면 데이터베이스에 시퀀스를 호출한 후 50까지는 메모리에서 시퀀스값을 저장한 이후 가상으로 증가시키며 관리합니다. 그리고 51이 되는 순간 시퀀스를 한 번 더 호출한 이후 값으로부터 50만큼인 100까지 가상으로 시퀀스 식별자를 관리합니다.

데이터베이스의 시퀀스 증가값이 1인 상태는 allocationSize또한 1으로 맞춰야 합니다.

  1. TABLE 전략
  • 키 생성 전용 테이블을 만든후 데이터베이스 시퀀스를 흉내내는 전략입니다.
  • 모든 데이터베이스에서 사용가능합니다.
  • 성능이 좋지 못합니다.

Key 생성 테이블

CREATE TABLE CUSTOM_SEQUENCE {
	sequence_name varchar(255) not null, // 시퀀스 이름
  next_val bigint, // 시퀀스 값
  primary key (sequence_name)
}

@TableGenerator을 사용하여 매핑합니다.

@Entity
@TableGenerator(
   name = "MEMBER_SEQ_GENERATOR",
   table = "CUSTOM_SEQUNECES",
   pkColumnValue = "MEMBER_SEQ", allocationSize = 1)
public class Member {

   @Id
   @GeneratedValue(strategy =GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
   private Long id;
}

해당 전략은 SEQUNCES 전략과 내부 동작이 같습니다.

pkColumnsValue의 시퀀스 이름을 Table의 sequence_name 컬럼에 생성해줍니다.

next_val의 Column이 값이 증가합니다, 만약 값이 없을 시 JPA가 INSERT 하면서 초기화를 하므로 값을 미리 넣어둘 필요는 없습니다.

  1. AUTO 전략
  • 데이터베이스의 종류에 따라 IDENTITY, TABLE, SEQUENCE 전략중 하나를 사용합니다.
  • 예를 들어 MySQL에선 IDENTY, Oracle에선 SEQUENCE를 사용합니다.
public class Member {

   @Id
   @GeneratedValue(strategy =GenerationType.AUTO)
   private Long id;
}

AUTO 전략은 GenerateValue의 기본값입니다.

해당 전략은 데이터베이스가 바뀌어도 코드를 수정할 필요가 없기 때문에 키 생성 전략이 확정되지 않은 개발 초기나 프로토타입 개발 시에 편리하게 이용이 가능합니다.

만약 AUTO로 SEQUENCE 또는 TABLE 전략을 사용시 에는 Sequnce나 키 생성 TABLE을 미리 생성해 두어야 합니다.


권장하는 식별자 전략

기본 키 제약조건

  • null 은 허용하지 않는다.
  • 변하지 않는다.
  • 유일하여야 한다.

기본키 2가지 전략

  • 자연키
    • 비즈니스에 의미 있는 키
    • 이메일, 전화번호
  • 대리키
    • 시스템쪽에 독립적으로 할당된 키
    • 키 생성 테이블, AUTO_INCREMENT, 오라클 시퀀스

자연키 보다는 대리키를 사용합니다.

현재에 자연 키가 조건을 만족을 하여도 미래에는 누락, 변경이 될 수도 있다.


Reference

https://www.inflearn.com/course/ORM-JPA-Basic

0개의 댓글

관련 채용 정보