[스프링 부트 쇼핑몰 프로젝트 with JPA] 8-1. [상품 관리] 상품 목록 조회 Querydsl

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

1. Qdomain 생성

  • Querydsl을 사용하기 위해서 Qdomain 생성

  • dependencies 부분 추가

  • build.gradle - [other] - [compileQuerydsl]

2. 상품 조회 조건 DTO

  • 상품 조회 조건
    • 상품 등록일
    • 상품 판매 상태
    • 상품명 또는 상품 등록자 아이디
  • 상품 조회 조건을 담을 ItemSearchDto 클래스 생성
import kr.spring.item.constant.ItemSellStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class ItemSearchDto {

    private String searchDateType;

    private ItemSellStatus searchSellStatus;

    private String searchBy;  // 방법(사람이름인지 상품 이름인지)

    private String searchQuery; // 검색
}

3. Querydsl & Spring Data Jpa

  • Querydsl과 Spring Data Jpa를 함께 사용하기 위해서는 사용자 정의 리포지토리가 필요함② 사용자 정의 인터페이스 구현
  • ③ Spring Data Jpa 리포지토리에서 사용자 정의 인터페이스 상속
  • ① 사용자 정의 인터페이스 작성

4. 사용자 정의 인터페이스 작성

  • 상품 조회 조건을 담고 있는 itemSearchDto 객체와 페이징 정보를 담고 있는 pageable 객체를 파라미터로 받고, Page<Item> 객체를 반환
import kr.spring.item.dto.ItemMainDto;
import kr.spring.item.dto.ItemSearchDto;
import kr.spring.item.entity.Item;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface ItemRepositoryCustom {

    // 몇 번째 페이지부터 몇 개를 가져올 건지
    Page<Item> getAdminItemPage(ItemSearchDto itemSearchDto, Pageable pageable);

}

5. 사용자 정의 인터페이스 구현

  • 클래스명 끝에 "Impl" 를 붙여야 정상적으로 동작함
  • 클래스 생성 및 사용자 정의 인터페이스 구현
public class ItemRepositoryCustomImpl implements ItemRepositoryCustom {

    private JPAQueryFactory queryFactory;

    public ItemRepositoryCustomImpl(EntityManager em) {
        queryFactory = new JPAQueryFactory(em);
    }
}
  • BooleanExpression 을 통해 where 절에 적용될 조회 조건을 생성
  • BooleanExpresiion 값이 null 이면 해당 조회 조건을 사용하지 않겠다는 의미 (=all)
  • 상품 등록일 조건
// ItemRepositoryCustomImpl 
private BooleanExpression regDtsAfter(String searchDateType) {

        LocalDateTime dateTime = LocalDateTime.now();

        if(StringUtils.equals("all", searchDateType) || searchDateType == null) {
            return null;
        } else if(StringUtils.equals("1d", searchDateType)) {
            dateTime = dateTime.minusDays(1);
        } else if(StringUtils.equals("1w", searchDateType)) {
            dateTime = dateTime.minusWeeks(1);
        } else if(StringUtils.equals("1m", searchDateType)) {
            dateTime = dateTime.minusMonths(1);
        } else if(StringUtils.equals("6m", searchDateType)) {
            dateTime = dateTime.minusMonths(6);
        }

        return item.regTime.after(dateTime);
    }
  • 상품 판매 상태 조건
private BooleanExpression searchSellStatusEq(ItemSellStatus searchSellStatus) {

        return searchSellStatus == null ? null : item.itemSellStatus.eq(searchSellStatus);
    }
  • 상품명 또는 상품 등록자 아이디 조건
private BooleanExpression searchByLike(String searchBy, String searchQuery) {

        // 방법에 따라 다름
        // 상품명에 따라 검색
        if(StringUtils.equals("itemNm", searchBy)) {
            return item.itemNm.like("%" + searchQuery + "%");
        }
        // 작성자에 따라 검색
        else if (StringUtils.equals("createdBy", searchBy)) {
            return item.createdBy.like("%" + searchQuery + "%");
        }

        return null;
    }
  • QueryFactory 를 이용하여 Querydsl 쿼리문 생성offset : 데이터를 가지고 올 시작 인덱스를 지정limit : 한 번에 가지고 올 최대 개수를 지정
  • fetchResult() 메소드를 이용하여 조회 대상 리스트 및 전체 개수를 포함하는 QueryResults 객체 반환
  • Page 클래스의 구현체인 PageImpl 객체로 반환
@Override
    public Page<Item> getAdminItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {

        List<Item> content = queryFactory
                .selectFrom(item)
                .where(regDtsAfter(itemSearchDto.getSearchDateType()),
                        searchSellStatusEq(itemSearchDto.getSearchSellStatus()),
                        // 어떤 방법으로 어떤 디비를 던질 것인지
                        searchByLike(itemSearchDto.getSearchBy(), itemSearchDto.getSearchQuery()))
                .orderBy(item.id.desc())
                .offset(pageable.getOffset()) // 시작할 위치
                .limit(pageable.getPageSize()) // 가져올 갯수
                .fetch(); // 리스트를 가져옴

        long total = queryFactory.select(Wildcard.count).from(item)
                                .where(regDtsAfter(itemSearchDto.getSearchDateType()),
                                    searchSellStatusEq(itemSearchDto.getSearchSellStatus()),
                                    searchByLike(itemSearchDto.getSearchBy(), itemSearchDto.getSearchQuery()))
                                .fetchOne();

        return new PageImpl<>(content, pageable, total);
    }

6. 사용자 정의 인터페이스 상속

  • JpaRepository 를 구현한 ItemRepository 에서 ItemRepositoryCustom을 상속
public interface ItemRepository extends JpaRepository<Item, Long>,
        QuerydslPredicateExecutor<Item>, ItemRepositoryCustom {

7. ItemService 수정

  • 위에서 만든 사용자 정의 조회문(=메소드)을 수행하는 로직 추가
  • 조회 기능이므로 읽기 전용 상태로 지정
// 정보 불러오기
public Page<Item> getAdminItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {

     return itemRepository.getAdminItemPage(itemSearchDto, pageable);

}

8. ItemController 수정

  • Mapping 파라미터로 객체를 지정하면(ItemSearchDto) 자동으로 new 객체 생성
  • URL을 통해 페이지 번호가 넘어오는 경우 @PathVariable로 변수 값 매핑
// 요청 URL에 페이지 번호가 없는 경우와 있는 경우 2가지를 매핑
    @GetMapping({"/admin/items", "/admin/items/{page}"})
    public String itemList(ItemSearchDto itemSearchDto, Model model,
                           @PathVariable("page")Optional<Integer> page) {

        // 페이지의 내용이 있으면 페이지 번호(page.get())을 가져오고 없으면 0으로 가져옴
        Pageable pageable = PageRequest.of(page.isPresent() ? page.get() : 0, 10);  // 한페이지에 표시되는 상품의 수를 관리(현재는 3개씩 보여줌)
        Page<Item> items = itemService.getAdminItemPage(itemSearchDto, pageable);

        model.addAttribute("items", items);
        // 검색어 다시 받아오기
        model.addAttribute("itemSearchDto", itemSearchDto);
        // View 단에서 하단에 보여줄 페이지 번호의 최대 개수 설정
        model.addAttribute("maxPage", 5);

        return "item/itemList";
    }
저작자표시 비영리 변경금지 (새창열림)

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

[스프링 부트 쇼핑몰 프로젝트 with JPA] 9. 메인화면  (0) 2023.10.16
[스프링 부트 쇼핑몰 프로젝트 with JPA] 8-2. [상품 관리] 상품 목록 페이지  (0) 2023.10.16
[스프링 부트 쇼핑몰 프로젝트 with JPA] 7. 상품 수정  (0) 2023.10.16
[스프링 부트 쇼핑몰 프로젝트 with JPA] 6-2. [상품 등록] Controller, Service, Repository  (0) 2023.10.15
[스프링 부트 쇼핑몰 프로젝트 with JPA] 6-1. [상품 등록] Entity, DTO, View  (0) 2023.10.15
'Web & Android/스프링 부트 쇼핑몰 프로젝트 with JPA' 카테고리의 다른 글
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 9. 메인화면
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 8-2. [상품 관리] 상품 목록 페이지
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 7. 상품 수정
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 6-2. [상품 등록] Controller, Service, Repository
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)
  • 블로그 메뉴

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

  • 태그

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

  • hELLO· Designed By정상우.v4.10.0
woojin._.
[스프링 부트 쇼핑몰 프로젝트 with JPA] 8-1. [상품 관리] 상품 목록 조회 Querydsl
상단으로

티스토리툴바