상품 엔티티 설계하기

진크·2022년 2월 21일
0
post-thumbnail

1. 상품 엔티티 설계하기

엔티티란 데이터베이스의 테이블에 대응하는 클래스라고 생각하면 됩니다. @Entity가 붙는 클래스는 JPA에서 관리하는 엔티티라고 합니다.

해당 도메인들을 관리할 domain 패키지를 만들고 그 하위 패키지로 items를 만들겠습니다.

package me.jincrates.gobook.domain.items;

public enum ItemSellStatus {
    SELL, SOLD_OUT
}
package me.jincrates.gobook.domain.items;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@ToString
@Getter
@NoArgsConstructor
@Entity
public class Item {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "item_id")
    private Long id; //상품 코드

    @Column(nullable = false, length = 50)
    private String itemNm; //상품명

    @Column(name = "price", nullable = false)
    private int price;  //가격

    @Column(nullable = false)
    private int stockNumber;  //재고수량

    @Lob
    @Column(nullable = false)
    private String itemDetail;  //상품 상세설명

    @Enumerated(EnumType.STRING)
    private ItemSellStatus itemSellStatus;  //상품 판매 상태

    @Builder
    public Item(String itemNm, int price, int stockNumber, String itemDetail, ItemSellStatus itemSellStatus) {
        this.itemNm = itemNm;
        this.price = price;
        this.stockNumber =stockNumber;
        this.itemDetail = itemDetail;
        this.itemSellStatus = itemSellStatus;
    }
}
  • enum 클래스를 사용하면 연관된 상수들을 모아둘 수 있으며 enum에 정의한 타입만 값을 가지도록 컴파일 시 체크할 수 있는 장점이 있습니다.
  • @Entity: 클래스를 엔티티로 선언
  • @Id: 테이블의 기존키에 사용할 속성을 지정
  • @GeneratedValue: 키 값을 생성하는 전량 명시
  • @Column: 필드와 맵핑
  • @Enumerated: enum 타입 매핑
  • @Builder: 해당 클래스의 빌더 패턴 클래스를 생성. 빌더를 사용하면 어떤 필드에 어떤 값을 채워야할지 명확하게 인지할 수 있습니다.

@GeneratedValue 전략

  • GenerationType.AUTO (default): JPA 구현체가 자동으로 생성 전략 결졍
  • GenerationType.IDENTITY: 기본키 생성을 데이터베이스에 위임
  • GenerationType.SEQUECE: 데이터베이스 시퀀스 오브젝트를 이용한 기본키 생성

프로젝트를 실행하면 Item 클래스가 MySQL Table로 생성된 것을 볼 수 있습니다.

2. Repository 설계하기

사실 Repository는 설계라고 할 것도 없습니다. 인터페이스 하나 생성해서 JpaRepository를 상속받기만 하면 됩니다.

package me.jincrates.gobook.domain.items;

import org.springframework.data.jpa.repository.JpaRepository;

public interface ItemRepository extends JpaRepository<Item, Long> {
}

JpaRepository에서 지원하는 메소드 예시

  • <S extends T> save(S entity): 엔티티 저장 및 수정
  • void delete(T entity): 엔티티 삭제
  • count(): 엔티티 총 개수 반환
  • Iterable<T> findAll(): 모든 엔티티 조회

테스트를 위한 application-test.yml 분리

# /src/main/resources/application-test.yml

spring:
    h2:
        console:
            enabled: true

    datasource:
        url: jdbc:h2:mem:testdb
        driverClassName: org.h2.Driver
        username: sa
        password:

    jpa:
        hibernate:
            ddl-auto: create
        properties:
            hibernate:
                show_sql: true
                format_sql: true
        database-platform: org.hibernate.dialect.H2Dialect

3. 테스트 코드 작성

인텔리제이를 인텔리하게 사용하는 법입니다. 해당 클래스를 클릭하시고 MAC 기준 단축키 Shipt + Alt + T를 누르고 Create New Test...를 누르면 손쉽게 테스트 코드를 작성하실 수 있습니다.

package me.jincrates.gobook.domain.items;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest
@TestPropertySource(properties = {"spring.config.location=classpath:application-test.yml"})
public class ItemRepositoryTest {

    @Autowired
    ItemRepository itemRepository;

    @Test
    @DisplayName("상품 저장 테스트")
    public void createItemTest() {
        Item item = Item.builder()
                .itemNm("테스트 상품")
                .price(10000)
                .itemDetail("테스트 상품 상세설명")
                .itemSellStatus(ItemSellStatus.SELL)
                .stockNumber(100)
                .build();
        Item savedItem = itemRepository.save(item);
        System.out.println(savedItem.toString());
    }
}
  • @SpringBootTest: 통합 테스트를 위해 스프링부트에서 제공하는 어노테이션입니다.
  • @TestPropertySource: 테스트 코드 실행시 application.yml에 설정해둔 값보다 application-test.yml에 같은 설정이 있다면 더 높은 우선순위를 부여합니다. 기존에는 MySQL을 사용했지만 테스트 코드 실행 시에는 H2 데이터베이스를 사용하게 됩니다.
  • @DisplayName: Junit5에 추가된 어노테이션으로 테스트코드 실행시 지정한 테스트명이 노출됩니다.

테스크 코드가 실행되면 콘솔창에 실행되는 쿼리문을 볼 수 있습니다. 별도의 insert query문 작성없이도 JPA를 통해 데이터를 insert를 할 수 있었습니다.

profile
철학있는 개발자 - 내가 무지하다는 것을 인정할 때 비로소 배움이 시작된다.

0개의 댓글