2025-04-08T19:56:24

This commit is contained in:
2025-04-08 19:56:24 +09:00
parent a75a1dbd0f
commit eef061c1c9
100 changed files with 18639 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
아래는 "기본 키 매핑"에 대해 예시와 함께 설명하는 글입니다. 롬복을 사용해 코드를 간결하게 유지했습니다.
---
### 기본 키 매핑
JPA에서 기본 키(Primary Key)는 엔티티를 식별하는 고유한 값으로, 데이터베이스 테이블의 각 레코드를 구분하는 데 사용됩니다. JPA는 `@Id` 어노테이션을 통해 기본 키를 지정하며, 기본 키 값을 자동으로 생성하는 다양한 전략을 제공합니다. 이를 "기본 키 매핑"이라고 부르며, `@GeneratedValue`와 함께 사용해 효율적으로 관리할 수 있습니다.
#### 기본 키 매핑의 주요 어노테이션
- **`@Id`**: 필드가 엔티티의 기본 키임을 나타냅니다. 모든 엔티티는 반드시 하나의 `@Id`를 가져야 합니다.
- **`@GeneratedValue`**: 기본 키 값을 자동 생성하도록 설정합니다. `strategy` 속성을 통해 생성 전략을 지정할 수 있습니다.
#### 기본 키 생성 전략
JPA는 네 가지 주요 기본 키 생성 전략을 제공합니다:
1. **`GenerationType.AUTO`**
- JPA 구현체(예: Hibernate)가 데이터베이스에 맞는 최적의 전략을 자동 선택합니다. 기본값이며, 환경에 따라 다르게 동작할 수 있습니다.
2. **`GenerationType.IDENTITY`**
- 데이터베이스의 `AUTO_INCREMENT` 기능을 사용합니다. MySQL, PostgreSQL 등에서 흔히 사용됩니다.
3. **`GenerationType.SEQUENCE`**
- 데이터베이스 시퀀스를 사용합니다. Oracle, PostgreSQL 등에서 지원됩니다.
4. **`GenerationType.TABLE`**
- 별도의 테이블을 만들어 기본 키 값을 관리합니다. 데이터베이스 종류에 상관없이 동작하지만 성능이 느릴 수 있습니다.
#### 예시: 기본 키 매핑
아래는 `Product` 엔티티를 통해 기본 키 매핑을 보여주는 예시입니다. 롬복을 사용해 코드를 간략화했습니다.
```java
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Column;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 자동 증가 전략
@Column(name = "product_id")
private Long id;
@Column(name = "product_name")
private String name;
@Column(name = "price")
private int price;
// 편의를 위한 생성자
public Product(String name, int price) {
this.name = name;
this.price = price;
}
}
```
#### 코드 설명
1. **`@Id``@GeneratedValue`**
- `id` 필드는 `@Id`로 기본 키임을 선언합니다.
- `@GeneratedValue(strategy = GenerationType.IDENTITY)`는 MySQL의 `AUTO_INCREMENT`처럼 데이터베이스가 기본 키 값을 자동으로 증가시키도록 설정합니다.
2. **동작 방식**
- `Product` 객체를 생성하고 저장(`persist`)하면, `id` 값은 개발자가 직접 지정하지 않아도 데이터베이스가 자동으로 1, 2, 3… 순으로 생성합니다.
- 예를 들어, `new Product("노트북", 1500000)`을 저장하면 데이터베이스에 다음과 같은 레코드가 삽입됩니다:
```
product_id: 1, product_name: "노트북", price: 1500000
```
#### 매핑된 테이블 구조
위 엔티티에 해당하는 테이블은 다음과 같습니다:
```sql
CREATE TABLE product (
product_id BIGINT PRIMARY KEY AUTO_INCREMENT,
product_name VARCHAR(255),
price INT
);
```
#### 시퀀스 사용 예시
만약 Oracle 데이터베이스를 사용한다면 `GenerationType.SEQUENCE`를 사용할 수 있습니다. 아래는 그 예시입니다.
```java
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.SequenceGenerator;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "order_seq")
@SequenceGenerator(name = "order_seq", sequenceName = "ORDER_SEQ", allocationSize = 1)
@Column(name = "order_id")
private Long id;
@Column(name = "order_amount")
private int amount;
public Order(int amount) {
this.amount = amount;
}
}
```
- **`@SequenceGenerator`**: `ORDER_SEQ`라는 데이터베이스 시퀀스를 정의합니다. `allocationSize`는 시퀀스 증가 단위를 지정합니다.
- 테이블과 별도로 `ORDER_SEQ` 시퀀스가 생성되며, `id` 값은 이 시퀀스에서 가져옵니다.
#### 선택 기준
- **`IDENTITY`**: 간단하고 성능이 좋아 MySQL 환경에서 추천됩니다.
- **`SEQUENCE`**: 대량 삽입 시 성능이 우수하며, Oracle 같은 시퀀스 지원 DB에서 적합합니다.
- **`AUTO`**: 데이터베이스에 의존하지 않고 유연하게 사용하려 할 때 유용합니다.
- **`TABLE`**: 데이터베이스 독립성을 보장해야 할 때 사용되지만, 실무에서는 드물게 선택됩니다.
#### 주의사항
- `@GeneratedValue`를 사용하지 않으면 개발자가 직접 기본 키 값을 설정해야 합니다.
- 기본 키는 `Long`, `Integer` 같은 래퍼 타입을 사용하는 것이 좋습니다. 기본형(`long`, `int`)은 0으로 초기화되므로 의도치 않은 동작을 방지할 수 있습니다.
---
기본 키 매핑은 JPA에서 데이터의 고유성을 보장하는 핵심 요소입니다. 적절한 생성 전략을 선택하면 개발 편의성과 성능을 모두 확보할 수 있습니다. 다음 장에서는 관계 매핑을 통해 엔티티 간 연결을 다뤄보겠습니다.
---
이 글이 책의 흐름에 적합한지, 추가 설명이나 수정이 필요하면 말씀해 주세요!