@Entity // 이 클래스를 데이터베이스의 엔티티로 선언
@Getter // Lombok 라이브러리를 사용하여 모든 필드의 getter 메서드 자동 생성
@Setter // Lombok 라이브러리를 사용하여 모든 필드의 setter 메서드 자동 생성
public class Member { // 회원을 나타내는 클래스
@Id // 이 필드가 테이블의 기본 키임을 선언
@GeneratedValue // 기본 키 값이 데이터베이스에 의해 자동으로 생성되어야 함을 선언
@Column(name = "member_id") // 데이터베이스의 컬럼 이름을 "member_id"로 지정
private Long id; // 회원 식별자
private String name; // 회원의 이름
@Embedded // 이 필드가 내장 타입임을 선언, Address 클래스의 필드들이 이 엔티티의 테이블 내에서 컬럼으로 포함됨
private Address address; // 회원의 주소
@OneToMany(mappedBy = "member") // 이 회원과 연관된 주문들의 리스트, "member" 필드에 의해 매핑됨
private List<Order> orders = new ArrayList<>(); // 회원의 주문 목록, 기본적으로 빈 리스트로 초기화
}
@GeneratedValue
@GeneratedValue는 Java Persistence API(JPA)에서 엔티티의 기본 키(primary key) 값이 어떻게 자동으로 생성될지를 명시하는 어노테이션입니다. 이 어노테이션은 주로 @Id 어노테이션과 함께 사용되어, 해당 엔티티의 식별자가 데이터베이스에 의해 자동으로 할당되도록 설정합니다.
사용법
@GeneratedValue 어노테이션은 다음과 같은 속성을 가질 수 있습니다:
- strategy: 식별자 생성 전략을 지정합니다. 사용할 수 있는 전략은 GenerationType 열거형에 정의된 값 중 하나를 사용합니다.
- generator: 식별자 생성기를 지정합니다. 이 속성은 주로 커스텀 생성기를 사용할 때 참조하는 이름입니다.
전략(Strategy)
GenerationType 열거형에서는 다음과 같은 주요 식별자 생성 전략을 제공합니다:
- AUTO (기본값): 특정 데이터베이스에 맞게 JPA 구현체가 자동으로 적절한 전략을 선택합니다.
- IDENTITY: 데이터베이스의 IDENTITY 컬럼을 사용하여 기본 키를 생성합니다. 이 전략은 데이터베이스가 새로운 레코드를 삽입할 때 자동으로 증가하는 숫자 값을 생성합니다. MySQL과 Microsoft SQL Server에서 사용됩니다.
- SEQUENCE: 데이터베이스의 시퀀스를 사용하여 기본 키를 생성합니다. 이 전략은 @SequenceGenerator 어노테이션과 함께 사용하여 시퀀스 이름과 함께 다른 매개변수를 명시할 수 있습니다. Oracle, PostgreSQL, DB2, H2 데이터베이스 등에서 사용됩니다.
- TABLE: 키 생성을 위해 별도의 테이블을 사용합니다. 이 테이블은 사용 가능한 키 값을 저장하고, 각 삽입 작업에 대해 키 값을 증가시킵니다. 이 전략은 특정 데이터베이스 기능에 의존하지 않기 때문에 데이터베이스 간 이식성이 뛰어납니다.
@Entity // 이 클래스를 데이터베이스 테이블에 매핑할 엔티티로 선언
@Table(name = "orders") // 이 엔티티가 매핑될 데이터베이스 테이블의 이름을 'orders'로 지정
@Getter // Lombok 라이브러리를 사용하여 모든 필드의 getter 메서드 자동 생성
@Setter // Lombok 라이브러리를 사용하여 모든 필드의 setter 메서드 자동 생성
public class Order { // 주문을 나타내는 클래스
@Id @GeneratedValue // 이 필드를 테이블의 기본 키로 설정하고, 값은 데이터베이스가 자동으로 생성
@Column(name = "order_id") // 데이터베이스의 컬럼 이름을 "order_id"로 지정
private Long id; // 주문의 고유 식별자
@ManyToOne // 다대일 관계를 나타내며, 여러 주문이 하나의 회원에게 속할 수 있음
@JoinColumn(name = "member_id") // 외래 키로 'member_id'를 사용
private Member member; // 이 주문을 한 회원
@OneToMany(mappedBy = "order") // 일대다 관계를 나타내며, 하나의 주문이 여러 주문 항목을 포함할 수 있음
private List<OrderItem> orderItems = new ArrayList<>(); // 주문 항목 목록
@OneToOne // 일대일 관계를 나타내며, 하나의 주문이 하나의 배송 정보를 가짐
@JoinColumn(name = "delivery_id") // 외래 키로 'delivery_id'를 사용
private Delivery delivery; // 이 주문의 배송 정보
private LocalDateTime orderDate; // 주문 날짜와 시간
@Enumerated(EnumType.STRING) // 이 필드를 열거형 타입으로 지정하며, 데이터베이스에 문자열로 저장
private OrderStatus status; // 주문 상태, 열거형 [ORDER, CANCEL] 값 중 하나를 가짐
}
package jpabook.jpashop.domain;
public enum OrderStatus {
ORDER, CANCEL
}
@Entity // 이 클래스를 데이터베이스 테이블에 매핑할 엔티티로 선언
@Getter // Lombok 라이브러리를 사용하여 모든 필드의 getter 메서드 자동 생성
@Setter // Lombok 라이브러리를 사용하여 모든 필드의 setter 메서드 자동 생성
public class OrderItem { // 주문 항목을 나타내는 클래스
@Id @GeneratedValue // 이 필드를 테이블의 기본 키로 설정하고, 값은 데이터베이스가 자동으로 생성
@Column(name = "order_item_id") // 데이터베이스의 컬럼 이름을 "order_item_id"로 지정
private Long id; // 주문 항목의 고유 식별자
@ManyToOne // 다대일 관계를 나타내며, 여러 주문 항목이 하나의 아이템에 속할 수 있음
@JoinColumn(name = "item_id") // 외래 키로 'item_id'를 사용
private Item item; // 이 주문 항목에 해당하는 상품
@ManyToOne // 다대일 관계를 나타내며, 여러 주문 항목이 하나의 주문에 속할 수 있음
@JoinColumn(name = "order_id") // 외래 키로 'order_id'를 사용
private Order order; // 이 주문 항목이 속한 주문
private int orderPrice; // 주문 가격
private int count; // 주문 수량
}
@Entity // 이 클래스를 데이터베이스 테이블에 매핑할 엔티티로 선언
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // 단일 테이블 상속 전략을 사용하여 모든 자식 클래스를 하나의 테이블에 저장
@DiscriminatorColumn(name = "dtype") // 상속된 엔티티를 구분할 컬럼 이름을 "dtype"로 지정
@Getter // Lombok 라이브러리를 사용하여 모든 필드의 getter 메서드 자동 생성
@Setter // Lombok 라이브러리를 사용하여 모든 필드의 setter 메서드 자동 생성
public abstract class Item { // 추상 클래스로 선언, 직접 인스턴스화할 수 없으며 상속을 통해 구체적인 아이템 클래스를 생성
@Id @GeneratedValue // 이 필드를 테이블의 기본 키로 설정하고, 값은 데이터베이스가 자동으로 생성
@Column(name = "item_id") // 데이터베이스의 컬럼 이름을 "item_id"로 지정
private Long id; // 상품의 고유 식별자
private String name; // 상품 이름
private int price; // 상품 가격
private int stockQuantity; // 상품 재고 수량
@ManyToMany(mappedBy = "items") // 다대다 관계를 나타내며, 여러 상품이 여러 카테고리에 속할 수 있음
private List<Category> categories = new ArrayList<>(); // 이 상품이 속한 카테고리 목록
}
@Entity // 이 클래스를 데이터베이스 테이블에 매핑할 엔티티로 선언
@Getter // Lombok 라이브러리를 사용하여 모든 필드의 getter 메서드 자동 생성
@Setter // Lombok 라이브러리를 사용하여 모든 필드의 setter 메서드 자동 생성
public class Category { // 카테고리를 나타내는 클래스
@Id @GeneratedValue // 이 필드를 테이블의 기본 키로 설정하고, 값은 데이터베이스가 자동으로 생성
@Column(name = "category_id") // 데이터베이스의 컬럼 이름을 "category_id"로 지정
private Long id; // 카테고리의 고유 식별자
private String name; // 카테고리 이름
@ManyToMany // 다대다 관계를 나타내며, 하나의 카테고리가 여러 상품을 포함할 수 있고, 하나의 상품이 여러 카테고리에 속할 수 있음
@JoinTable(name = "category_item", // 다대다 관계를 매핑하는 연결 테이블을 지정
joinColumns = @JoinColumn(name = "category_id"), // 현재 엔티티를 연결 테이블에 매핑하는 컬럼
inverseJoinColumns = @JoinColumn(name = "item_id")) // 연결된 다른 엔티티를 연결 테이블에 매핑하는 컬럼
private List<Item> items = new ArrayList<>(); // 이 카테고리에 속한 상품 목록
@ManyToOne // 다대일 관계를 나타내며, 하위 카테고리가 하나의 상위 카테고리에 속할 수 있음
@JoinColumn(name = "parent_id") // 상위 카테고리와 연결되는 외래 키 컬럼
private Category parent; // 이 카테고리의 상위 카테고리
@OneToMany(mappedBy = "parent") // 일대다 관계를 나타내며, 하나의 카테고리가 여러 하위 카테고리를 포함할 수 있음
private List<Category> child = new ArrayList<>(); // 이 카테고리의 하위 카테고리 목록
}
테이블, 컬럼명 생성 전략
스프링 부트에서 하이버네이트 기본 매핑 전략을 변경해서 실제 테이블 필드명은 다름
https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#howto-configure-hibernate-naming-strategy
http://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html#naming
CascadeType.ALL
CascadeType.ALL은 해당 엔티티에 대해 수행되는 모든 생명주기 변경(생성, 업데이트, 삭제 등)이 관련 엔티티에도 적용되도록 지정합니다. 구체적으로는 다음과 같은 CascadeType들을 모두 포함합니다:
- PERSIST: 엔티티를 영속화할 때(저장할 때), 연관된 엔티티도 함께 영속화됩니다.
- REMOVE: 엔티티를 삭제할 때, 연관된 엔티티도 함께 삭제됩니다.
- MERGE: 엔티티 상태를 병합할 때, 연관된 엔티티의 상태도 함께 병합됩니다.
- REFRESH: 엔티티를 새로 고칠 때, 연관된 엔티티도 함께 새로 고쳐집니다.
- DETACH: 엔티티가 영속성 컨텍스트에서 분리될 때, 연관된 엔티티도 함께 분리됩니다.
사용 예
예를 들어, Order 엔티티와 OrderItem 엔티티가 있고, Order 엔티티에 여러 OrderItem 엔티티가 연관되어 있다고 가정해 봅시다. 여기서 Order 엔티티에 cascade = CascadeType.ALL을 설정하면, Order 엔티티를 저장할 때 연관된 모든 OrderItem 엔티티도 자동으로 저장됩니다. 또한, Order 엔티티를 삭제할 경우 연관된 모든 OrderItem 엔티티도 함께 삭제됩니다.