ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 쇼핑몰 프로젝트 --아이템조회, 삭제, 아이템전체리스트조회 (화면구현)
    쇼핑몰 프로젝트 2024. 6. 19. 03:17

     

     

    조회하기 전에 수정부분을 조금 수정했다. 
    원래 데이터를 받아오게 하려고 
    itemController

    //수정보기
    @GetMapping("/ypjs/item/update/{itemId}")
    public String udateItem(@PathVariable("itemId") Long itemId, Model model) {
        Item findItem = itemService.findOneItem(itemId);
    
        System.out.println(findItem);
    
        ItemUpdateDto item =  new ItemUpdateDto(
                findItem.getItemId(),
                findItem.getCategory().getCategoryId(),
                findItem.getItemName(),
                findItem.getItemContent(),
                findItem.getItemPrice(),
                findItem.getItemStock());
    
        model.addAttribute("item", item);
    
    
    
        return "item/itemUpdate";
    }
    
    
    
    
    
    //수정등록
    @PostMapping("/ypjs/item/update/{itemId}")
    public String updateItem(@PathVariable("itemId") Long itemId,
                                    @RequestParam("file") MultipartFile file,
                                    @Valid @ModelAttribute  ItemUpdateDto itemUpdateDto,
                                    @Valid @ModelAttribute  ItemFileDto itemFileDto, Model model) throws Exception {
    
        itemService.updateItem(itemId, itemUpdateDto, itemFileDto, file);
        Item findItem = itemService.findOneItem(itemId);
    
    
        return "item/itemPost";
    
    }
    

     

    @GetMapping에 dto를 추가했다. 

     

     

    item/itemUpdate

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" lang="en">
    
    <head th:replace="frame/header :: head">
        <title>Zay Shop - Product Listing Page</title>
    </head>
    
    <body>
    <!--header-->
    <header th:replace="frame/header :: header"></header>
    
    <!-- Start Content -->
    <div class="container py-5">
        상품수정
    </div>
    <!-- End Content -->
    
    
    
    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <!-- Summernote 스타일 및 스크립트 -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote-bs4.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote-bs4.min.js"></script>
    
    
    
    <!-- JS 파일 포함 -->
    <script src="/js/jquery-1.11.0.min.js"></script>
    <script src="/js/summernote-lite.js"></script>
    <script src="/js/summernote-ko-KR.js"></script>
    <script src="/js/item/item.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote.min.js"></script>
    
    
    
    
    
    <!-- Start Contact -->
    <div class="container py-5">
        <div class="row py-5">
            <form th:action="@{/ypjs/item/update/{itemId}(itemId=${item.itemId})}" class="col-md-9 m-auto" method="post" th:object="${item}" enctype="multipart/form-data">
    
                <!-- 폼 요소들 -->
                <div class="row">
                    <div class="form-group mb-3">
                        <label for="categoryId">카테고리 번호</label>
                        <input type="text" class="form-control mt-1" id="categoryId" name="categoryId"  th:value="${item.categoryId}" placeholder="카테고리 번호">
                    </div>
                    <div class="form-group mb-3">
                        <label for="itemName">상품명</label>
                        <input type="text" class="form-control mt-1" id="itemName" name="itemName" th:value="${item.itemName}" placeholder="상품명">
                    </div>
                    <div class="form-group mb-3">
                        <label for="itemPrice">상품가격</label>
                        <input type="text" class="form-control mt-1" id="itemPrice" name="itemPrice" th:value="${item.itemPrice}" placeholder="상품가격">
                    </div>
                    <div class="form-group mb-3">
                        <label for="itemStock">상품수량</label>
                        <input type="text" class="form-control mt-1" id="itemStock" name="itemStock" th:value="${item.itemStock}" placeholder="상품수량">
                    </div>
    
                    <div class="form-group mb-3">
                        <label>썸네일 업로드하기</label>
    
    
                        <div class="btn-upload">
                            <input type="file" name="file" id="file" onchange="displayFileName(this)">
                            <!-- 파일 업로드 필드에는 id와 name 속성이 모두 필요합니다. -->
                        </div>
                        <div id="file-name-display"></div>
                    </div>
    
                    <div class="mb-3">
                        <label>상품내용</label>
                        <textarea class="form-control" id="itemContent" name="itemContent" th:utext="${item.itemContent}" rows="10"></textarea>
                    </div>
                </div>
    
                <!-- Summernote 초기화 스크립트 -->
                <script th:inline="javascript">
                    $(document).ready(function() {
                        $("#itemContent").summernote({
                            height: 600, // 높이 설정
                            placeholder: '상품 내용을 입력하세요...', // 플레이스홀더 설정
                            callbacks: {
                                onChange: function(contents, $editable) {
                                    // 내용이 변경될 때 처리할 로직 추가 가능
                                }
                            }
                        });
                    });
    
                    // 파일명을 표시하는 함수
                    function displayFileName(input) {
                        if (input.files.length > 0) {
                            var fileName = input.files[0].name;
                            document.getElementById('file-name-display').innerText = '선택된 파일: ' + fileName;
                        } else {
                            document.getElementById('file-name-display').innerText = '';
                        }
                    }
                </script>
    
                <!-- 글 등록 버튼 -->
                <div class="row">
                    <div class="col text-end mt-2">
                        <!--                    <button type="button" id="btn-itemPost" class="btn btn-success btn-lg px-3">상품저장</button>-->
                        <button type="submit" class="btn btn-success btn-md">상품수정</button>
                    </div>
                </div>
            </form>
        </div>
    </div>
    <!-- End Contact -->
    
    <!-- Start Brands -->
    <section class="bg-light py-5">
        <div class="container my-4">
            <div class="row text-center py-3">
                <div class="col-lg-6 m-auto">
                    <h1 class="h1">Our Brands</h1>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
                        Lorem ipsum dolor sit amet.
                    </p>
                </div>
                <div class="col-lg-9 m-auto tempaltemo-carousel">
                    <div class="row d-flex flex-row">
                        <!--Controls-->
                        <div class="col-1 align-self-center">
                            <a class="h1" href="#multi-item-example" role="button" data-bs-slide="prev">
                                <i class="text-light fas fa-chevron-left"></i>
                            </a>
                        </div>
                        <!--End Controls-->
    
                        <!--Carousel Wrapper-->
                        <div class="col">
                            <div class="carousel slide carousel-multi-item pt-2 pt-md-0" id="multi-item-example" data-bs-ride="carousel">
                                <!--Slides-->
                                <div class="carousel-inner product-links-wap" role="listbox">
    
                                    <!--First slide-->
                                    <div class="carousel-item active">
                                        <div class="row">
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_01.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_02.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_03.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_04.png" alt="Brand Logo"></a>
                                            </div>
                                        </div>
                                    </div>
                                    <!--End First slide-->
    
                                    <!--Second slide-->
                                    <div class="carousel-item">
                                        <div class="row">
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_01.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_02.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_03.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_04.png" alt="Brand Logo"></a>
                                            </div>
                                        </div>
                                    </div>
                                    <!--End Second slide-->
    
                                    <!--Third slide-->
                                    <div class="carousel-item">
                                        <div class="row">
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_01.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_02.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_03.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_04.png" alt="Brand Logo"></a>
                                            </div>
                                        </div>
                                    </div>
                                    <!--End Third slide-->
    
                                </div>
                                <!--End Slides-->
                            </div>
                        </div>
                        <!--End Carousel Wrapper-->
    
                        <!--Controls-->
                        <div class="col-1 align-self-center">
                            <a class="h1" href="#multi-item-example" role="button" data-bs-slide="next">
                                <i class="text-light fas fa-chevron-right"></i>
                            </a>
                        </div>
                        <!--End Controls-->
                    </div>
                </div>
            </div>
        </div>
    </section>
    <!--End Brands-->
    
    
    <footer th:replace="frame/footer :: footer"></footer>
    
    </body>
    
    </html>
    

     

    html에도 받아오는 부분을 추가했다.

     

     

    아이템 조회

    //item1개 조회
    @GetMapping("/ypjs/item/get/{itemId}")
    public String getOneItem (@PathVariable("itemId") Long itemId,
                                  Model model) {
    
        Item findItem = itemService.findOneItem(itemId);
    
        ItemOneDto item = new ItemOneDto(
                findItem.getItemId(),
                findItem.getItemName(),
                findItem.getItemContent(),
                findItem.getItemPrice(),
                findItem.getItemRatings(),
                findItem.getItemCreateDate(),
                findItem.getItemCnt(),
                findItem.getItemReviews()
    
        );
    
    
        model.addAttribute("item", item);
    
        //조회수
        itemService.increaseItemCnt(itemId);
    
        //리뷰리스트
        itemReviewService.findAllItemReview(itemId);
    
    
    
        return "item/itemGet";
    
    }

    컨트롤러 부분을 수정했고 

     

     

    dto도 수정했다. 

    itemOneDto

    package ypjs.project.dto.itemdto;
    
    import lombok.Data;
    import lombok.Getter;
    import ypjs.project.domain.Item;
    import ypjs.project.domain.ItemReview;
    
    import java.time.LocalDateTime;
    import java.util.List;
    import java.util.stream.Collectors;
    
    @Data
    public class ItemOneDto {
    
        private Long itemId;
        private String itemName;
        private String itemContent;
        private int itemPrice;
        private double itemRatings;
        private LocalDateTime itemCreateDate;
        private int itemCnt;
    
        private List<ItemReviewListDto> itemReviews;
    
    
        public ItemOneDto(Long itemId, String itemName, String itemContent, int itemPrice, Double itemRatings,
                          LocalDateTime itemCreateDate, int itemCnt, List<ItemReview> itemReviews) {
            this.itemId = itemId;
            this.itemName = itemName;
            this.itemContent = itemContent;
            this.itemPrice = itemPrice;
            this.itemRatings = itemRatings;
            this.itemCreateDate = itemCreateDate;
            this.itemCnt = itemCnt;
    
            this.itemReviews = itemReviews.stream()
                    .map(ItemReviewListDto::new)
                    .collect(Collectors.toList());
        }
    
    
        public ItemOneDto(Item item) {
            this.itemId = item.getItemId();
            this.itemName = item.getItemName();
            this.itemContent = item.getItemContent();
            this.itemPrice = item.getItemPrice();
            this.itemRatings = item.getItemRatings();
            this.itemCreateDate = item.getItemCreateDate();
            this.itemCnt = item.getItemCnt();
    
            this.itemReviews = item.getItemReviews().stream()
                    .map(ItemReviewListDto::new)
                    .collect(Collectors.toList());
        }
    }
    

     

     

     

    item/itemGet

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" lang="en">
    
    <head th:replace="frame/header :: head">
        <title>Zay Shop - Product Listing Page</title>
    </head>
    
    <body>
    <!--header-->
    <header th:replace="frame/header :: header"></header>
    
    <style>
        .bg-light {
            background-color: transparent !important; /* 배경색을 투명하게 설정 */
        }
    
        /* 요소의 우선순위를 높여서 Bootstrap의 font-weight-bold 클래스가 적용될 수 있도록 함 */
        h1.font-weight-bold, span.font-weight-bold {
            font-weight: bold !important;
        }
    
         .custom-mt {
            margin-top: -20px; /* 원하는 간격 값으로 설정 */
        }
    
    </style>
    
    <script src="/js/item/item.js"></script>
    
    
    
    
    <!-- Open Content -->
    
    
    <div class="card-body pt-4 mt-3"> <!-- pt-4를 mt-3으로 변경 -->
        <div class="row">
            <div class="col-lg-7 offset-lg-1 text-right">
                <h1 class="h2 mb-3 font-weight-bold" th:text="${item.itemName}"></h1>
                <span id="itemPrice" class="font-weight-bold" th:text="${item.itemPrice}"></span>
                <span class="font-weight-bold">원</span>
                <p class="h3 py-2"></p>
            </div>
        </div>
    </div>
    
    
    <div class="col-lg-7 custom-mt  offset-lg-1"> <!-- custom-mt 클래스 추가하여 간격 조정 -->
        <div class="card border-0 bg-transparent"> <!-- border-0와 bg-transparent 클래스 추가 -->
            <p class="py-2">
                <i class="fa fa-star text-warning"></i>
                <i class="fa fa-star text-warning"></i>
                <i class="fa fa-star text-warning"></i>
                <i class="fa fa-star text-warning"></i>
                <i class="fa fa-star text-secondary"></i>
                <span class="list-inline-item text-dark"> 4.8 |  Reviews</span>
            </p>
        </div>
    </div>
    
    
    <div class="container">
        <div class="row justify-content-end">
            <div class="col-auto">
                <a th:href="@{/ypjs/item/update/{itemId}(itemId=${item.itemId})}" class="btn btn-warning">수정하기</a>
            </div>
            <div class="col-auto">
                <input type="hidden" id="itemId" th:value="${item.itemId}">
                <button type="button" id="btn-itemDelete" class="btn btn-danger">삭제하기</button>
            </div>
        </div>
    </div>
    
    <br>
    
    <div class="container">
        <div class="row justify-content-end">
            <div class="col-auto">
                <span class="font-weight-bold"> 조회수 : </span>
                <span id="itemCnt" class="font-weight-bold" th:text="${item.itemCnt}"></span>
                <br>
                <span class="font-weight-bold">작성일 : </span>
                <span id="itemCreateDate" class="font-weight-bold" th:text="${#temporals.format(item.itemCreateDate, 'yyyy-MM-dd')}"></span>
    
    
    
    
            </div>
            <div class="col-auto">
    
            </div>
        </div>
    </div>
    <hr>
    
    
    
    
    <section class="bg-light">
        <div class="container pb-5 text-center"> <!-- text-center 클래스 추가 -->
            <div class="col-lg-5 mt-5 d-block mx-auto"> <!-- d-block mx-auto 클래스 추가 -->
                <span id="itemContent" th:utext="${item.itemContent}"></span>
            </div>
        </div>
    </section>
    
    
    
    
    
    
    
    <div class="row pb-3">
        <div class="col-lg-6 offset-lg-5"> <!-- offset-lg-6 클래스 추가하여 오른쪽으로 옮김 -->
            <ul class="list-inline pb-3 text-right"> <!-- text-right 클래스 추가하여 내용 오른쪽 정렬 -->
                <li class="list-inline-item">
                    수량
                    <input type="hidden" name="product-quanity" id="product-quanity" value="1">
                </li>
                <li class="list-inline-item"><span class="btn btn-success" id="btn-minus">-</span></li>
                <li class="list-inline-item"><span class="badge bg-secondary" id="var-value">1</span></li>
                <li class="list-inline-item"><span class="btn btn-success" id="btn-plus">+</span></li>
            </ul>
        </div>
    </div>
    
    <div class="row pb-3">
        <div class="col d-grid">
            <button type="submit" class="btn btn-success btn-md" name="submit" value="buy">Buy</button>
        </div>
        <div class="col d-grid">
            <button type="submit" class="btn btn-success btn-md" name="submit" value="addtocard">Add To Cart</button>
        </div>
    </div>
    
    </form>
    
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
    <!-- Close Content -->
    
    
    
    
    
    
    <footer th:replace="frame/footer :: footer"></footer>
    
    </body>
    
    </html>

     

     

    이 화면이 나온다 일단 강아지 사진으로 업로드

     

     

     

    삭제

    itemController

    //삭제
    @DeleteMapping("/ypjs/item/delete/{itemId}")
    public @ResponseBody ResponseDto<?> deleteItem(@PathVariable("itemId") Long itemId) {
        itemService.deleteItem(itemId);
        return new ResponseDto<>(HttpStatus.OK.value(), "아이템이 삭제되었습니다.");
    }

     

    컨트롤러를 조금 수정했다. 

     

     

    item.js

    let itemBoardObject = {
        init: function() {
            let _this = this;
    
            $("#btn-itemPost").on("click", function() {
                alert("상품 저장 버튼 클릭됨");
                _this.insert();
            }),
            $("#btn-itemDelete").on("click", () => {
                      _this.delete();
                   });
        },
    
        insert: function() {
            alert("글 등록이 요청되었습니다.");
    
            let data = {
                categoryId: $("#categoryId").val(),
                itemName: $("#itemName").val(),
                itemPrice: $("#itemPrice").val(),
                itemStock: $("#itemStock").val(),
                itemContent: $("#summernote").summernote('code') // Summernote의 HTML 내용 가져오기
    
            };
    
            $.ajax({
                type: "POST",
                url: "/ypjs/item/post",
                data: JSON.stringify(data),
                contentType: "application/json; charset=utf-8",
                enctype: 'multipart/form-data', // 추가
                success: function(response) {
                        window.location.href = "/test";
                },
                error: function(error) {
                    alert("에러 발생: " + JSON.stringify(error));
                }
            });
        },
    
        delete: function() {
                // itemId 가져오기
                let itemId = $("#itemId").val();
    
                $.ajax({
                    type: "DELETE",
                    url: "/ypjs/item/delete/" + itemId,
                    success: function(response) {
                        alert(response.data); // 성공 메시지 처리
                        window.location.href = "/test"; // 삭제 후 페이지 이동
                    },
                    error: function(xhr, status, error) {
                        alert("에러 발생: " + error);
                    }
                });
            }
        };
    
    
    $(document).ready(function() {
        itemBoardObject.init();
    });
    

     

     

    delete부분을 추가하고 

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" lang="en">
    
    <head th:replace="frame/header :: head">
        <title>Zay Shop - Product Listing Page</title>
    </head>
    
    <body>
    <!--header-->
    <header th:replace="frame/header :: header"></header>
    
    <style>
        .bg-light {
            background-color: transparent !important; /* 배경색을 투명하게 설정 */
        }
    
        /* 요소의 우선순위를 높여서 Bootstrap의 font-weight-bold 클래스가 적용될 수 있도록 함 */
        h1.font-weight-bold, span.font-weight-bold {
            font-weight: bold !important;
        }
    
         .custom-mt {
            margin-top: -20px; /* 원하는 간격 값으로 설정 */
        }
    
    </style>
    
    <script src="/js/item/item.js"></script>
    
    
    
    
    <!-- Open Content -->
    
    
    <div class="card-body pt-4 mt-3"> <!-- pt-4를 mt-3으로 변경 -->
        <div class="row">
            <div class="col-lg-7 offset-lg-1 text-right">
                <h1 class="h2 mb-3 font-weight-bold" th:text="${item.itemName}"></h1>
                <span id="itemPrice" class="font-weight-bold" th:text="${item.itemPrice}"></span>
                <span class="font-weight-bold">원</span>
                <p class="h3 py-2"></p>
            </div>
        </div>
    </div>
    
    
    <div class="col-lg-7 custom-mt  offset-lg-1"> <!-- custom-mt 클래스 추가하여 간격 조정 -->
        <div class="card border-0 bg-transparent"> <!-- border-0와 bg-transparent 클래스 추가 -->
            <p class="py-2">
                <i class="fa fa-star text-warning"></i>
                <i class="fa fa-star text-warning"></i>
                <i class="fa fa-star text-warning"></i>
                <i class="fa fa-star text-warning"></i>
                <i class="fa fa-star text-secondary"></i>
                <span class="list-inline-item text-dark"> 4.8 |  Reviews</span>
            </p>
        </div>
    </div>
    
    
    <div class="container">
        <div class="row justify-content-end">
            <div class="col-auto">
                <a th:href="@{/ypjs/item/update/{itemId}(itemId=${item.itemId})}" class="btn btn-warning">수정하기</a>
            </div>
            <div class="col-auto">
                <input type="hidden" id="itemId" th:value="${item.itemId}">
                <button type="button" id="btn-itemDelete" class="btn btn-danger">삭제하기</button>
            </div>
        </div>
    </div>
    
    <br>
    
    <div class="container">
        <div class="row justify-content-end">
            <div class="col-auto">
                <span class="font-weight-bold"> 조회수 : </span>
                <span id="itemCnt" class="font-weight-bold" th:text="${item.itemCnt}"></span>
                <br>
                <span class="font-weight-bold">작성일 : </span>
                <span id="itemCreateDate" class="font-weight-bold" th:text="${#temporals.format(item.itemCreateDate, 'yyyy-MM-dd')}"></span>
    
    
    
    
            </div>
            <div class="col-auto">
    
            </div>
        </div>
    </div>
    <hr>
    
    
    
    
    <section class="bg-light">
        <div class="container pb-5 text-center"> <!-- text-center 클래스 추가 -->
            <div class="col-lg-5 mt-5 d-block mx-auto"> <!-- d-block mx-auto 클래스 추가 -->
                <span id="itemContent" th:utext="${item.itemContent}"></span>
            </div>
        </div>
    </section>
    
    
    
    
    
    
    
    <div class="row pb-3">
        <div class="col-lg-6 offset-lg-5"> <!-- offset-lg-6 클래스 추가하여 오른쪽으로 옮김 -->
            <ul class="list-inline pb-3 text-right"> <!-- text-right 클래스 추가하여 내용 오른쪽 정렬 -->
                <li class="list-inline-item">
                    수량
                    <input type="hidden" name="product-quanity" id="product-quanity" value="1">
                </li>
                <li class="list-inline-item"><span class="btn btn-success" id="btn-minus">-</span></li>
                <li class="list-inline-item"><span class="badge bg-secondary" id="var-value">1</span></li>
                <li class="list-inline-item"><span class="btn btn-success" id="btn-plus">+</span></li>
            </ul>
        </div>
    </div>
    
    <div class="row pb-3">
        <div class="col d-grid">
            <button type="submit" class="btn btn-success btn-md" name="submit" value="buy">Buy</button>
        </div>
        <div class="col d-grid">
            <button type="submit" class="btn btn-success btn-md" name="submit" value="addtocard">Add To Cart</button>
        </div>
    </div>
    
    </form>
    
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
    <!-- Close Content -->
    
    
    
    
    
    
    <footer th:replace="frame/footer :: footer"></footer>
    
    </body>
    
    </html>

     

    상품보기 페이지도 만들었다. 

     

     

     

    item전체조회

    내가 아이템을 전체 조회하는 코드가 없어서 추가했다. 

     

     

    itemRepository

    //아이템 전체 조회
    public List<Item> findAllItem(String keyword, Pageable pageable, String sortBy) {
        String queryString = "select i from Item i";
    
        // 검색 조건 추가
        boolean hasKeyword = (keyword != null && !keyword.isEmpty());
        if (hasKeyword) {
            queryString += " where i.itemName like :keyword";
        }
    
        // 기본 정렬 조건
        queryString += " order by i.itemId desc"; // 최신순으로 정렬 (itemId가 클수록 최신 데이터)
    
        // 추가 정렬 조건
        if ("itemRatings".equals(sortBy)) {
            queryString += ", i.itemRatings desc";
        } else if ("likeCount".equals(sortBy)) {
            queryString += ", i.likeCount desc";
        }
    
        TypedQuery<Item> query = em.createQuery(queryString, Item.class)
                .setFirstResult((int) pageable.getOffset())
                .setMaxResults(pageable.getPageSize());
    
        // 검색 키워드 파라미터 설정
        if (hasKeyword) {
            query.setParameter("keyword", "%" + keyword + "%");
        }
    
        return query.getResultList();
    }

     

     

    itemService

    //아이템 전체 조회
    public List<ItemListDto> findAllItem(String keyword, Pageable pageable, String sortBy) {
        List<Item> items = itemRepository.findAllItem(keyword, pageable, sortBy);
    
    
        List<ItemListDto> result = items.stream()
                .map(ItemListDto::new)
                .collect(Collectors.toList());
    
        return result;
    
    }
    

     

     

    itemController

    //아이템 전체 조회
    @GetMapping("/ypjs/item/get")
    public String getAllItem(
                                     @RequestParam(value = "page",defaultValue = "0") int page,
                                     @RequestParam(value = "size",defaultValue = "3") int size,
                                     @RequestParam(value = "sortBy", defaultValue = "itemId") String sortBy,
                                     @RequestParam(value = "keyword", required = false) String keyword,
                                     Model model) {
    
        Pageable pageable = PageRequest.of(page, size);
    
        List<ItemListDto> items = itemService.findAllItem(keyword, pageable, sortBy);
    
        model.addAttribute("items", items);
    
    
        return "item/itemList";
    
    
    }
    

     

     

     

    itemListDto도 추가했다. 

    package ypjs.project.dto.itemdto;
    
    import lombok.Data;
    import lombok.Getter;
    import ypjs.project.domain.Item;
    
    @Data
    public class ItemListDto {
    
        private Long itemId;
        private String itemName;
        private String itemContent;
        private int itemPrice;
        private int itemStock;
        private double itemRatings;
        private String itemFilePath;
        private int itemCnt;
    
        public ItemListDto() {}
    
        public ItemListDto(Item item) {
    
            itemId = item.getItemId();
            itemName = item.getItemName();
            itemContent = item.getItemContent();
            itemPrice = item.getItemPrice();
            itemStock = item.getItemStock();
            itemRatings = item.getItemRatings();
            itemFilePath = item.getItemFilepath();
            itemCnt = item.getItemCnt();
    
        }
    
    
    
    
    }
    

     

     

     

    item/itemList

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" lang="en">
    
    <head th:replace="frame/header :: head">
        <title>Zay Shop - Product Listing Page</title>
    </head>
    
    <body>
    <!--header-->
    <header th:replace="frame/header :: header"></header>
    
    <!-- Start Content -->
    <div class="container py-5">
        <div class="row">
    
            <div class="col-lg-3">
                <h1 class="h2 pb-4">Categories</h1>
                <ul class="list-unstyled templatemo-accordion">
                    <li class="pb-3">
                        <a class="collapsed d-flex justify-content-between h3 text-decoration-none" href="#">
                            Women
                            <i class="fa fa-fw fa-chevron-circle-down mt-1"></i>
                        </a>
                        <ul class="collapse show list-unstyled pl-3">
                            <li><a class="text-decoration-none" th:href="@{/ypjs/categoryItem/get/{categoryId}(categoryId=3)}">Outer</a></li>
                            <li><a class="text-decoration-none" href="#">Top</a></li>
                            <li><a class="text-decoration-none" href="#">Bottom</a></li>
                        </ul>
                    </li>
                    <li class="pb-3">
                        <a class="collapsed d-flex justify-content-between h3 text-decoration-none" href="#">
                            Man
                            <i class="pull-right fa fa-fw fa-chevron-circle-down mt-1"></i>
                        </a>
                        <ul id="collapseTwo" class="collapse list-unstyled pl-3">
                            <li><a class="text-decoration-none" href="#">Outer</a></li>
                            <li><a class="text-decoration-none" href="#">Top</a></li>
                            <li><a class="text-decoration-none" href="#">Bottom</a></li>
                        </ul>
                    </li>
    
                </ul>
            </div>
    
            <div class="col-lg-9">
                <div class="row">
                    <div class="col-md-6">
                        <ul class="list-inline shop-top-menu pb-3 pt-1">
                            <li class="list-inline-item">
                                <a class="h3 text-dark text-decoration-none mr-3" th:href="@{/ypjs/item/get}">All Items</a>
                            </li>
    
                        </ul>
                    </div>
    
    
                    <div class="col-md-6 pb-4">
                        <div class="d-flex">
                            <select class="form-control">
                                <option>최신순</option>
                                <option>별점높은순</option>
                                <option>찜많은순</option>
                            </select>
                        </div>
                    </div>
                </div>
    
    <!--            <div class="container-fluid mt-3">-->
    <!--                <div class="row">-->
    <!--                    &lt;!&ndash; items.content가 아니라 items를 반복하며 각각의 ItemListDto 객체를 처리 &ndash;&gt;-->
    <!--                    <div th:each="item : ${items}" class="col-md-3 mb-4">-->
    <!--                        <div class="product-card image-zoom-effect link-effect d-flex flex-wrap">-->
    <!--                            <div class="image-holder">-->
    <!--                                &lt;!&ndash; itemId를 이용하여 링크를 생성 &ndash;&gt;-->
    <!--                                <a th:href="@{/ypjs/item/get/{itemId}(itemId=${item.itemId})}">-->
    <!--                                    &lt;!&ndash; item을 사용하여 itemFilepath 속성을 가져옴 &ndash;&gt;-->
    <!--                                    <img th:src="${item.itemFilePath}" alt="product-item" class="product-image img-fluid">-->
    <!--                                </a>-->
    <!--                            </div>-->
    
    <!--                            <div class="image-holder">-->
    <!--                                &lt;!&ndash; item을 사용하여 itemCnt 속성을 가져옴 &ndash;&gt;-->
    <!--                                <h6 th:text="${item.itemCnt}">Count</h6>-->
    <!--                            </div>-->
    <!--                        </div>-->
    <!--                    </div>-->
    <!--                </div>-->
    <!--            </div>-->
    
                <div class="container-fluid mt-3">
                    <div class="row">
                        <!-- items 리스트의 각 항목을 반복 -->
                        <div th:each="item : ${items}" class="col-md-4">
                            <div class="card mb-4 product-wap rounded-0">
                                <!-- 제품 이미지 -->
                                <div class="card rounded-0">
                                    <a th:href="@{/ypjs/item/get/{itemId}(itemId=${item.itemId})}">
                                    <img class="card-img rounded-0 img-fluid" th:src="${item.itemFilePath}" alt="product-item">
                                    <!-- 필요한 경우 오버레이나 추가 요소를 여기에 추가할 수 있습니다 -->
                                    <div class="card-img-overlay rounded-0 product-overlay d-flex align-items-center justify-content-center">
                                        <!-- 추가적인 콘텐츠가 필요하다면 여기에 추가할 수 있습니다 -->
                                        <ul class="list-unstyled">
                                            <!-- 리스트의 다른 요소들 -->
                                        </ul>
                                    </div>
                                </div>
                                <!-- 제품 정보 -->
                                <div class="card-body">
                                    <!-- 제품 링크 -->
                                    <a th:href="@{/ypjs/item/get/{itemId}(itemId=${item.itemId})}" id="itemName" class="font-weight-bold" th:text="${item.itemName}"></a>
    
    
                                    <!-- 별점 표시 -->
                                    <ul class="list-unstyled d-flex justify-content-center mb-1">
                                        <li>
                                            <i class="text-warning fa fa-star"></i>
                                            <i class="text-warning fa fa-star"></i>
                                            <i class="text-warning fa fa-star"></i>
                                            <i class="text-muted fa fa-star"></i>
                                            <i class="text-muted fa fa-star"></i>
                                        </li>
                                    </ul>
                                    <!-- 가격 표시 -->
                                    <span id="itemPrice" class="font-weight-bold" th:text="${item.itemPrice}"></span>
                                    <span class="font-weight-bold">원</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
    
    
    
    
    
    
    
                </div>
            </div>
    
        </div>
    </div>
    <!-- End Content -->
    
    <!-- Start Brands -->
    <section class="bg-light py-5">
        <div class="container my-4">
            <div class="row text-center py-3">
                <div class="col-lg-6 m-auto">
                    <h1 class="h1">Our Brands</h1>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
                        Lorem ipsum dolor sit amet.
                    </p>
                </div>
                <div class="col-lg-9 m-auto tempaltemo-carousel">
                    <div class="row d-flex flex-row">
                        <!--Controls-->
                        <div class="col-1 align-self-center">
                            <a class="h1" href="#multi-item-example" role="button" data-bs-slide="prev">
                                <i class="text-light fas fa-chevron-left"></i>
                            </a>
                        </div>
                        <!--End Controls-->
    
                        <!--Carousel Wrapper-->
                        <div class="col">
                            <div class="carousel slide carousel-multi-item pt-2 pt-md-0" id="multi-item-example" data-bs-ride="carousel">
                                <!--Slides-->
                                <div class="carousel-inner product-links-wap" role="listbox">
    
                                    <!--First slide-->
                                    <div class="carousel-item active">
                                        <div class="row">
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_01.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_02.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_03.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_04.png" alt="Brand Logo"></a>
                                            </div>
                                        </div>
                                    </div>
                                    <!--End First slide-->
    
                                    <!--Second slide-->
                                    <div class="carousel-item">
                                        <div class="row">
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_01.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_02.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_03.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_04.png" alt="Brand Logo"></a>
                                            </div>
                                        </div>
                                    </div>
                                    <!--End Second slide-->
    
                                    <!--Third slide-->
                                    <div class="carousel-item">
                                        <div class="row">
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_01.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_02.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_03.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_04.png" alt="Brand Logo"></a>
                                            </div>
                                        </div>
                                    </div>
                                    <!--End Third slide-->
    
                                </div>
                                <!--End Slides-->
                            </div>
                        </div>
                        <!--End Carousel Wrapper-->
    
                        <!--Controls-->
                        <div class="col-1 align-self-center">
                            <a class="h1" href="#multi-item-example" role="button" data-bs-slide="next">
                                <i class="text-light fas fa-chevron-right"></i>
                            </a>
                        </div>
                        <!--End Controls-->
                    </div>
                </div>
            </div>
        </div>
    </section>
    <!--End Brands-->
    
    
    <footer th:replace="frame/footer :: footer"></footer>
    
    </body>
    
    </html>

     

     

    다 하면 이 화면이 나온다

     

     

    화면에서 페이징을 어떻게하는 지 모르겠어서 일단 안했다. 거의 다 구현하고 할 예정

Designed by Tistory.