
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 }
'개인공부' 카테고리의 다른 글
[ Pydantic ] Pydantic의 BaseModel 사용하기 (0) | 2024.05.28 |
---|---|
[ JPA ] 다양한 어노테이션을 사용한 효과적인 엔터티 매핑_2.연관관계 매핑 (0) | 2024.02.12 |
[ JPA ] JPA Entity, EntityManagerFactory, EntityManager, Persistence context (0) | 2024.02.11 |
[ JPA ] JPA 에 관하여 (1) | 2024.02.11 |
일잘하는 사람들의 소통법 (0) | 2024.02.09 |