[스프링 부트 쇼핑몰 프로젝트 with JPA] 6-1. [상품 등록] Entity, DTO, View

2023. 10. 15. 10:33·Web & Android/스프링 부트 쇼핑몰 프로젝트 with JPA
이 내용은 스프링 부트 쇼핑몰 프로젝트 with JPA 책을 학습한 내용입니다.

1. 상품 이미지 Entity

  • Item (상품) Entity 와 다대일 단방향 관계를 갖는 ItemImg Entity 생성
package kr.spring.item.entity;

import jakarta.persistence.*;
import kr.spring.utils.entity.BaseEntity;
import lombok.*;

@Entity
@Getter
@Setter // 필수 아님
@ToString // 문자열 자동 생성
@NoArgsConstructor // 빈생성자 생성
public class ItemImg extends BaseEntity {

    @Id //기본키 설정
    @GeneratedValue(strategy = GenerationType.IDENTITY) //mysql의 경우 identity를 사용.
    @Column(name = "item_img_id")  //name 속성은 column의 이름을 변경할 수 있다.
    private Long id;                     // 이미지 코드

    private String imgName; // 이미지 파일명

    private String oriImgName; // 원본 파일명

    private String imgUrl; // 이미지 경로

    private String repImgYn; // 대표 이미지 여부

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "item_id")
    private Item item;

    public void updateItemImg(String oriImgName, String imgName, String imgUrl) {
        this.oriImgName = oriImgName;
        this.imgName = imgName;
        this.imgUrl = imgUrl;
    }
}

2. modelmapper 라이브러리 추가

// modelmappter 추가 -> dto <-> entity
    implementation 'org.modelmapper:modelmapper:3.1.1'
  • DTO 객체와 Entity 객체의 변환을 도와줌
  • 서로 다른 클래스의 값을 필드의 이름과 자료형이 같으면 getter, setter를 통해 값을 복사해서 객체를 반환

3. 상품 관련 DTO 객체 생성

  • 상품을 등록 및 조회할 때 지정된 필드뿐 아니라 추가적인 데이터들의 이동이 많으므로 여러 DTO 이용
  • 상품 이미지에 대한 DTO
  • ItemImg 엔티티 객체를 ItemImgDto 객체로 변환
package kr.spring.item.dto;

import kr.spring.item.entity.ItemImg;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.modelmapper.ModelMapper;

@Getter
@Setter
@ToString // 내용 확인을 위해 사용
public class ItemImgDto {

    private Long id;  // 이미지 코드

    private String imgName; // 이미지 파일명

    private String oriImgName; // 원본 파일명

    private String imgUrl; // 이미지 경로

    private String repImgYn; // 대표 이미지 여부

    private static ModelMapper modelMapper = new ModelMapper();

    // 엔티티로 변환
    public static ItemImgDto of(ItemImg itemImg) {
        return modelMapper.map(itemImg, ItemImgDto.class); // mapping 걸기
    }
}
  • 화면으로부터 입력 받은 상품 데이터 정보 DTO
  • Item 엔티티 객체와 DTO 객체 간의 변환
package kr.spring.item.dto;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import kr.spring.item.entity.Item;
import lombok.Getter;
import lombok.Setter;
import org.modelmapper.ModelMapper;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Getter // 반드시 붙여야 함
@Setter // 필수는 아님
public class ItemFormDto {

    private Long id;                     // 상품 코드

    @NotBlank(message = "상품명은 필수 항목입니다.")
    private String itemNm;               // 상품 이름

    @NotNull(message = "가격은 필수 항목입니다.")
    private int price;                   // 상품 가격

    @NotNull(message = "재고는 필수 항목입니다.")
    private int stockNumber;             // 재고 수량

    private String itemSellStatus;

    @NotBlank(message = "상품 설명은 필수 항목입니다.")
    private String itemDetail;           // 상품 상세 설명

    private List<ItemImgDto> itemImgDtoList = new ArrayList<>(); // imgDtoList 관리

    private List<Long> itemImgList = new ArrayList<>(); // 이미지들에 대한 번호 관리

    private static ModelMapper modelMapper = new ModelMapper(); // 엔티티와 매핑

    public Item createItem() {
        return modelMapper.map(this, Item.class); // dto를 엔티티로 변환
    }

    public static ItemFormDto of(Item item) {
        return modelMapper.map(item, ItemFormDto.class); // 엔티티를 dto로 변환
    }
}

4. ItemController

  • ItemFormDto 객체를 model 객체에 담아서 뷰로 전달
@Controller
@RequiredArgsConstructor // @Autowired로도 쓸 수 있음
public class ItemController {

    // 웹 페이지로 이동
    @GetMapping("/admin/item/new")
    public String itemForm(Model model) {
        model.addAttribute("itemFormDto", new ItemFormDto());

        return "item/itemForm";
    }

5. ItemForm View

  • 상품 판매 상태를 “판매중” 또는 “품절”로 선택할 수 있게 <select> 태그 이용

<!-- 상품 판매 상태는 판매 중/품절로 나뉜다. -->
            <div class="form-group">
                  <select th:field="*{itemSellStatus}" class="custom-select">
                        <option value="SELL">판매중</option>
                        <option value="SOLD_OUT">품절</option>
                  </select>
            </div>
  • 상품을 처음 등록할 경우 Controller를 통해 전달 받은 itemFormDtoList가 존재하지 않음
  • Thymeleaf builtin 메소드 #numbers.sequence() 를 통해서 1 부터 5 까지 상품이미지명 출력
<!--            #numbers.sequence(start,end)를 이용하여 반복처리. 최대 이미지 등록 갯수는 5개. -->
                  <div class="form-group" th:each="num: ${#numbers.sequence(1,5)}">
                        <div class="custom-file img-div">
                              <!--  나중에 name에 해당되는 itemImgFile을 들고 날라간다 똑같은 이름이 다섯 번 나타날 때 얘가 어떻게 처리되는지를 봐야 함 -->
                              <input type="file" class="custom-file-input" name="itemImgFile">
                              <!--                    몇 번째 상품 이미지인지 표시 -->
                              <label class="custom-file-label" th:text="상품이미지 + ${num}"></label>
                        </div>
                  </div>
  • 상품을 수정할 경우는 이미 존재하던 상품 이미지가 있으므로 itemFormDtoList가 존재함
  • 이미지가 존재하면 해당 이미지의 이름을 출력하고 빈칸이면 상품이미지+index를 출력
<!--  비어있지 않고 뭔가 들고 날라온 경우 그러니까 수정을 위함 -->
            <div th:if="${not #lists.isEmpty(itemFormDto.itemImgDtoList)}">
                  <div class="form-group"
                       th:each="itemImgDto, status: ${itemFormDto.itemImgDtoList}">
                        <div class="custom-file img-div">
                              <!--  일단 거기에 있는 정보를 다 가지고 올 거야  -->
                              <input type="file" class="custom-file-input" name="itemImgFile">
                              <!--                특정 상품 수정/삭제 시 어떤 이미지가 수정됐는지 알기 위해 상품 이미지의 아이디를 hidden으로 숨겨둔다. -->
                              <input type="hidden" name="itemImgIds" th:value="${itemImgDto.id}">
                              <label class="custom-file-label"
                                     th:text="${not #strings.isEmpty(itemImgDto.oriImgName)} ? ${itemImgDto.oriImgName} : '상품이미지' + ${status.index+1}"></label>
                        </div>
                  </div>
            </div>
  • 상품을 처음 등록할 때는 “저장”버튼을 출력
  • 상품을 수정할 때는 “수정”버튼을 출력
!--상품아이디가 없는 경우 저장 로직을 호출하는 버튼 보여줌. 원래 form 태그에서 지정해줘야하지만 아이디를 체크해서 없는 경우 fromaction을 이용하여 new로 준다-->
            <div th:if="${#strings.isEmpty(itemFormDto.id)}"
                 style="text-align: center">
                  <button th:formaction="@{'/admin/item/new'}" type="submit"
                          class="btn btn-primary">저장</button>
            </div>
            <!--        저장된 이미지 정보가 있다면 파일의 이름을 보여주고, 없다면 상품 이미지 + 번호를 보여준다. -->
            <div th:unless="${#strings.isEmpty(itemFormDto.id)}"
                 style="text-align: center">
                  <!--            상품 아이디가 있는 경우 수정 로직을 호출하는 벼튼을 보여줌-->
                  <button th:formaction="@{'/admin/item/' + ${itemFormDto.id} }"
                          type="submit" class="btn btn-primary">수정</button>
            </div>

6. 상품 등록 페이지 화면

저작자표시 비영리 변경금지 (새창열림)

'Web & Android > 스프링 부트 쇼핑몰 프로젝트 with JPA' 카테고리의 다른 글

[스프링 부트 쇼핑몰 프로젝트 with JPA] 7. 상품 수정  (0) 2023.10.16
[스프링 부트 쇼핑몰 프로젝트 with JPA] 6-2. [상품 등록] Controller, Service, Repository  (0) 2023.10.15
[스프링 부트 쇼핑몰 프로젝트 with JPA] 5. Entity 공통 속성 공통화(Auditing)  (0) 2023.10.15
[스프링 부트 쇼핑몰 프로젝트 with JPA] 4. 페이지 권한 설정  (0) 2023.10.15
[스프링 부트 쇼핑몰 프로젝트 with JPA] 3. 로그인/로그아웃  (0) 2023.10.15
'Web & Android/스프링 부트 쇼핑몰 프로젝트 with JPA' 카테고리의 다른 글
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 7. 상품 수정
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 6-2. [상품 등록] Controller, Service, Repository
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 5. Entity 공통 속성 공통화(Auditing)
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 4. 페이지 권한 설정
woojin._.
woojin._.
여러가지 개발을 해보며 발생하는 이야기들에 대한 블로그입니다:)
  • woojin._.
    Jin's Dev Story
    woojin._.
  • 전체
    오늘
    어제
    • 분류 전체보기 (829)
      • Tools (25)
        • eGovFrame (3)
        • GeoServer (3)
        • QGIS (2)
        • LabelImg (2)
        • Git (6)
        • GitHub (1)
        • Eclipse (7)
        • Visual Studio (1)
      • Web & Android (121)
        • SpringBoot (37)
        • Three.js (2)
        • Spring Data JPA (9)
        • 스프링 부트 쇼핑몰 프로젝트 with JPA (25)
        • Thymeleaf (4)
        • Spring Security (15)
        • Flutter (29)
      • Programming Language (61)
        • JAVA (27)
        • JavaScript (14)
        • Dart (2)
        • Python (15)
        • PHP (3)
      • Database (43)
        • PostgreSQL (32)
        • MYSQL (7)
        • Oracle (3)
        • MSSQL (1)
      • SERVER (17)
        • TCP_IP (3)
        • 리눅스 (7)
        • AWS (7)
      • Coding Test (445)
        • 백준[JAVA] (108)
        • 프로그래머스[JAVA] (260)
        • 알고리즘 고득점 Kit[JAVA] (3)
        • SQL 고득점 Kit[ORACLE] (74)
      • CS 지식 (49)
        • [자료구조] (14)
        • [네트워크] (12)
        • [데이터베이스] (10)
        • [알고리즘] (9)
        • [운영체제] (4)
      • 기타 (6)
      • 자격증 & 공부 (62)
        • 정보처리기사 (2)
        • SQLD (6)
        • 네트워크관리사 2급 (5)
        • 리눅스마스터 1급 (44)
        • 리눅스마스터 2급 (1)
        • ISTQB (3)
        • 시스템보안 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 인기 글

  • 태그

    JPA
    Java
    springboot
    Linux
    spring
    programmers
    프로그래머스
    Spring Security
    DB
    Oracle
    backjoon
    스프링
    데이터베이스
    baekjoon
    데이터
    CS
    리눅스마스터 1급
    python
    Flutter
    postgresql
    리눅스
    시큐리티
    리눅스마스터
    스프링 부트 쇼핑몰 프로젝트 with JPA
    CS지식
    pcce 기출문제
    백준
    스프링부트
    플러터
    자바
  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
woojin._.
[스프링 부트 쇼핑몰 프로젝트 with JPA] 6-1. [상품 등록] Entity, DTO, View
상단으로

티스토리툴바