엔티티 매핑(1) - 엔티티, 기본 키 매핑

2023. 12. 29. 19:16spring/JPA

JPA를 사용하는 데 가장 중요한 일은 엔티티와 테이블을 정확히 매핑하는 것이다.

JPA는 다양한 매핑 어노테이션을 지원하는데 크게 4가지로 분류할 수 있다.

 

 - 객체와 테이블 : @Entity, @Table

 - 기본 키 : @Id

 - 필드와 컬럼 : @Column

 - 연관관계 매핑 : @ManyToOne, @JoinColumn

 

먼저 객체와 테이블 매핑을 살펴보자

1.@Entity

테이블과 매핑할 클래스에 @Entity 어노테이션을 필수로 붙여야 한다. JPA가 관리하는 클래스로 엔티티라 부른다.

 - name 속성 : 엔티티 이름 지정. 보통 클래스 이름을 사용한다.

@Entity(name = "member2")
public class Member {
}

=> member2 테이블과 Member 클래스를 매핑한다.

 

*주의사항

 - 기본 생성자는 필수다

(private으로 하면 안됨. 리플렉션을 이용해서 클래스를 조작하는데 외부에서 객체 생성을 못하게 만들기 때문)

 

 - final 클래스, enum, interface, inner 클래스에는 사용할 수 없다.

(지연로딩을 위해 프록시 객체를 만드는데, 확장을 할 수 없는 클래스라 사용할 수 없음)

(inner 클래스는 객체를 생성하기 위해 enclosing한 클래스를 먼저 인스턴스화 해야하기 때문)

 

 - 저장할 필드에 final을 사용하면 안된다.

(역시 리플렉션을 이용해 setter 메서드로 값을 주입하는데, final 필드에는 주입할 수 없음)

 

 

2.@Table

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

 

*속성

 - name : 매핑할 테이블 이름

 - catalog : catalog 기능이 있는 데이터베이스에서 catalog를 매핑한다.

 - schema  : schema 기능이 있는 데이터베이스에서 schema를 매핑한다.

 - uniqueConstraints : DDL 생성 시에 유니크 제약조건을 만든다. 스키마 자동 생성 기능을 사용할 때만 사용된다.

 

 

 

3. @Id

@Entity()
public class Member {
    @Id
    private Long id;
}

 

기본 키를 직접 할당하지 않고 데이터베이스가 생성해주는 값을 사용할 수 있다.

JPA는 데이터베이스마다 기본 키를 생성하는 방식이 서로 다르므로 여러가지 전략을 이용해 기본 키를 할당 받는다.

 

자동생성 : 대리 키 사용 방식

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

 - SEQUENCE : 데이터베이스 시퀀스를 사용해서 기본 키를 할당한다.

 - TABLE : 키 생성 테이블을 사용한다.

 

*TABLE 전략은 키 생성용 테이블을 하나 만들어두고 시퀀스처럼 사용하는 방법이다.

 

기본 키를 직접 할당하려면@Id만 사용하면 되고, 자동 생성 전략을 사용하려면 @Id에 @GeneratedValue를 추가하고 원하는 키 생성 전략을 선택하면 된다.

 

IDENTITY 전략

IDENTITY는 기본 키 생성을 데이터베이스에 위임하는 전략이다. MySQL, PostgreSQL, SQL Server, DB2에서 사용한다.

MySql은 auto_increment 기능이 수행되는데 데이터베이스에 저장되고 나서야 기본 키 값을 구할 수 있다.

@Entity
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
}

 

그래서 영속화를 하면 지연쓰기 하지 않고 바로 insert한 후에 id 값을 할당한다.

 

SEQUENCE 전략

데이터베이스 시퀀스는 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트다. SEQUENCE 전략은 이 시퀀스를 사용해서 기본 키를 생성한다.

 

Member member = new Member();
member.setAge(13);

entityManager.persist(member);

System.out.println("=========before commit=========");

tx.commit();

 

member 객체를 영속화하면 데이터베이스에 다음 시퀀스를 요청해 id 값에 할당한다.

 

매번 영속화를 진행할 때마다 DB와 연결하는데, 성능을 걱정한다면 allocationSize를 지정해서 시퀀스를 한 번 호출해 메모리에 미리 생성된 id 값을 올려두고 사용할 수 있다.

 

sequence generator를 명시하지 않는다면 같은 시퀀스 생성기를 공유하니 엔티티의 시퀀스 생성기를 명시해서 따로 사용할 수 있다.

 

@SequenceGenerator(
        name = "MEMBER_SEQ_GENERATOR",
        sequenceName = "MEMBER_SEQ",
        initialValue = 1, allocationSize = 50
)
@Entity
public class Member {
    @Id
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "MEMBER_SEQ_GENERATOR"
    )
    private Long id;
}

 

SEQUENCE 전략은 위에서 잠깐 언급했던 것처럼 entityManager.persist()를 호출할 때 먼저 데이터베이스 시퀀스를 사용해서 식별자를 조회한다. 그리고 조회한 식별자를 엔티티에 할당한 후에 엔티티를 영속성 컨텍스트에 저장한다.

 

AUTO 전략

선택한 데이터베이스 Dialect에 맞게 IDENTITY, SEQUENCE, TABLE 전략 중 하나를 자동으로 선택한다.

'spring > JPA' 카테고리의 다른 글

고급매핑 - 상속 관계 매핑  (0) 2024.01.15
연관관계 매핑(2) - 단방향, 양방향  (0) 2024.01.04
엔티티 매핑(2) - 컬럼 매핑  (0) 2024.01.03
영속성 관리(2)  (0) 2023.12.28
영속성 관리(1)  (1) 2023.12.28