개인공부

[ JPA ] 다양한 어노테이션을 사용한 효과적인 엔터티 매핑_1.객체와 테이블 매핑

KEEMSY 2024. 2. 12. 22:23
JPA 알고쓰자.. 공부하자..공부..!

 
 
JPA 어노테이션을 효과적으로 사용하는 방법을 아는 것은 애플리케이션에서 데이터베이스와의 상호작용을 최대한으로(아마도) 잘 활용하기 위해서는 필수적이라고 생각한다.  그리고 나는 이 작업을 잘하고 싶다.
 
그래서 이번 정리를 통해, JPA 어노테이션을 카테고리별로 나눠 정리함으로써, JPA 를 활용한 모델링을 더 잘 이해하고 활용할 수 있을 것이라고 기대한다.
 


객체와 테이블 매핑 어노테이션

 

 
객체(Entity)와 데이터 베이스의 Table 을 매핑 할 때에는 주로 다음과 같은 어노테이션이 사용된다.
 

@Entity

JPA 에서 테이블에 매핑할 클래스에 붙인다. 이 어노테이션이 붙은 클래스는 엔티티로 불린다.

  • privaet 혹은 protected 인 기본 생성자(default constructor)를 반드시 작성해야한다.
  • final clss, enum, interface, inner class 에는 사용이 불가능하다. (final 필드 또한 사용불가)

@Table

엔티티와 매핑할 테이블 이름을 지정한다.

  • name: 테이블의 이름
  • schema: 데이터베이스의 스키마
  • catalog: 테이블의 데이터베이스 카탈로그
  • uniqueConstraints: 테이블 열에 고유한 제약 조건을 지정하는데 사용

@Id

엔티티의 유니크한 식별을 위해 사용되는 기본 키로 사용되는 필드에 사용한다. @GeneratedValue 어노테이션을 통해 다양한 기본키 생성 전략을 사용할 수 있다.
 

기본 키 매핑 전략

1. 직접 할당하는 방법
Member member = new Member();
member.setId("MEMBER_00001");  // pk 직접 생성 후 지정한다.
em.persist(member);

- 기본키는 변경되지 않되기 때문에, 직접 할당하는 방법을 사용하는 경우를 제외하고는 setId() 메서드는 private 처리하는 것이 좋다.

2. IDENTITY 를 사용하는 방법

@Entity
@Table(name="members")
public class Member {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private String id;
    ...
}


3. SEQUENCE 를 사용하는 방법

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


4. TABLE  을 사용하는 방법

@Entity
@SequenceGenerator(name="MEMBER_SEQ_GENERATOR", table="TB_SEQUENCE", pkColumnValue="ORDER_SEQ", allocationSize=1)
@Table(name="members")
public class Member {
    @Id
    @GeneratedValue(strategy=GenerationType.TABLE, getnerator="MEMBER_SEQ_GENERATOR")
    private String id;
    ...
}

 

@GeneratedValue

영속성 컨텍스트에 엔티티를 저장하려면 반드시 식별자가 필요하기 때문에, 기본 키 생성 전략이 필요하며, @GeneratedValue 는 기본키를 매핑 하는 전략을 나타낸다.

  • IDENTITY
    • 기본키 생성을 데이터베이스에 위임한다. 이 경우, MySQL에서 AUTO_INCREMENT 를 지정해 둔 경우 사용한다. IDENTITY 전략 사용시 즉시 DB반영된다.(쓰기지연 X)
  • SEQUENCE: 데이터베이스 시퀀스를 사용하여 고유 값을 생성한다.
  • TABLE: 데이터베이스 테이블을 사용하여 고유성을 보장한다. SEQUENCE 와 비슷하게 기본키를 생성한다.
  • AUTO: 지속성 공급자가 최상의 전략을 결정하도록 한다.

@Column

엔티티 필드를 데이터베이스 열에 매핑한다.

  • name: 데이터베이스의 열 이름을 지정한다.
  • nullable: 열이 null일 수 있는지 여부를 나타낸다.
  • length: 열 길이(주로 문자열 데이터 유형에 사용됨).
  • unique: 열 값이 고유해야 하는지 여부를 나타낸다.

@Enumerated

필드를 열거형 유형으로 유지하도록 지정한다.  열거형(문자열 또는 일반형;STRING or ORDINAL)을 지정할 수 있다.

@Temporal

데이터베이스에서 사용되는 SQL 유형(DATE, TIME, or TIMESTAMP)을 지정하기 위해 java.util.Date 및 java.util.Calendar 클래스와 함께 사용된다.

@Lob

필드가 CLOB(Character Large Object) 또는 BLOB(Binary Large Object)와 같은 큰 객체로 유지되어야 함을 나타낸다.

@Transient

영속성 프레임워크에서 무시할 필드를 의미한다. 데이터베이스에서 지속되지 않을 필드를 표시한다.

@Access

필드 액세스(AccessType.FIELD) 또는 속성 액세스(AccessType.PROPERTY)를 통해 JPA가 엔티티의 값에 액세스하는 방법을 지정한다.

  • FILED: 기본값으로, 직접 필드에 접근한다.
  • PROPERTY: getter를 통해 접근한다.

@Embedded and @Embeddable

클래스를 다른 엔티티의 일부로 임베드하는 데 사용된다.

  • @Embedded: 필드에 선언
  • @Embeddable: 클래스에 선언

@AttributeOverride and @AttributeOverrides

임베드 가능한 클래스에 정의된 열 매핑을 재정의할 수 있다.
임베더블 클래스가 여러 엔티티에서 사용되는 경우 속성을 재정의하는 데 유용하다.
 

Basic Entity Mapping
import javax.persistence.*;

@Entity
@Table(name = "employees")
public class Employee {

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

    @Column(name = "first_name", nullable = false)
    private String firstName;

    @Column(name = "last_name", nullable = false)
    private String lastName;

    @Enumerated(EnumType.STRING)
    private Role role;

    // Constructors, Getters, and Setters
}

 

Embeddable Object Example
@Embeddable
public class Address {
    private String street;
    private String city;
    private String state;
    private String zipCode;

    // Constructors, Getters, and Setters
}

@Entity
@Table(name = "users")
public class User {

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

    @Embedded
    private Address address;

    // Constructors, Getters, and Setters
}

 

Overriding Embedded Attributes
@Entity
@Table(name = "suppliers")
public class Supplier {

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

    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "street", column = @Column(name = "supplier_street")),
        @AttributeOverride(name = "city", column = @Column(name = "supplier_city"))
    })
    private Address address;

    // Constructors, Getters, and Setters
}

 
 

Association Override
@Entity
public class Department {

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

    @AssociationOverride(
        name = "employees",
        joinTable = @JoinTable(
            name = "dept_employees",
            joinColumns = @JoinColumn(name = "department_id"),
            inverseJoinColumns = @JoinColumn(name = "employee_id")
        )
    )
    @OneToMany
    private List<Employee> employees;

    // Constructors, Getters, and Setters
}
728x90