[스프링 부트 쇼핑몰 프로젝트 with JPA] 9. 메인화면

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

1. MainItemDto

  • 메인화면에 출력할 데이터를 위한 DTO 객체
  • 사용자에게 보여질 내용만 포함하고 있음 (등록날짜, 수정날짜, 등록자 등 제외)
import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ItemMainDto {

    private Long id;

    private String itemNm;

    private String itemDetail;

    private String imgUrl;

    private Integer price;

    @QueryProjection
    public ItemMainDto(Long id, String itemNm, String itemDetail, String imgUrl, Integer price) {
        this.id = id;
        this.itemNm = itemNm;
        this.itemDetail = itemDetail;
        this.imgUrl = imgUrl;
        this.price = price;
    }
}

2. @QueryProjection

  • Entity 객체를 DTO 객체로 바로 반환하도록 지원하는 어노테이션
  • @QueryProjection을 이용하여 상품 조회 시 DTO 객체로 결과 값을 받는 방법
  • @QueryProjection을 이용하면 Item 객체로 값을 받은 후 DTO 클래스로 변환하는 과정 없이 바로 DTO 객체 뽑아낼 수 있음

3. 사용자 정의 인터페이스 리포지토리 생성

  • 기존의 ItemRepositoryCustom 클래스에 조회문 추가
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<ItemMainDto> getItemMainPage(ItemSearchDto itemSearchDto, Pageable pageable);
}
  • ItemRepositoryCustomImpl 클래스에서 getMainItemPage() 메소드 구현
// 검색어가 포함된 상품 조회 조건 BooleanExpression
    private BooleanExpression itemNmLike(String searchQuery) {
        return StringUtils.isEmpty(searchQuery) ? null : item.itemNm.like("%" + searchQuery + "%");
    }
@Override
    public Page<ItemMainDto> getItemMainPage(ItemSearchDto itemSearchDto, Pageable pageable) {

        QItem item = QItem.item;
        QItemImg itemImg = QItemImg.itemImg;

        QueryResults<ItemMainDto> results = queryFactory
								// MainItemDto 객체를 반환
								// 멤버변수 초기화는 조회된 결과값에서 MainItemDto 객체 생성자를 통해 지정
								// 즉, db 조회 결과는 itemImg-item 조인된 결과가 반환되지만 그 중 일부만 사용
                .select(
                        new QItemMainDto(
                                item.id,
                                item.itemNm,
                                item.itemDetail,
                                itemImg.imgUrl,
                                item.price)
                        )
                .from(itemImg)
								// itemImg 테이블의 item 필드가 참조하는 item 테이블 조인
                .join(itemImg.item, item)
								// 5개의 이미지중에서 대표사진만을 조회
                .where(itemImg.repimgYn.eq("Y"))
                .where(itemNmLike(itemSearchDto.getSearchQuery()))
                .orderBy(item.id.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetchResults();

        List<ItemMainDto> content = results.getResults();
        long total = results.getTotal();
        return new PageImpl<>(content, pageable, total);

    }
  • ItemService 에 getMainItemPage() 메소드 수행 로직 추가
@Transactional(readOnly = true)
    public Page<ItemMainDto> getItemMainDto(ItemSearchDto itemSearchDto, Pageable pageable) {
        return itemRepository.getItemMainPage(itemSearchDto, pageable);
    }

4. Main Controller

  • 화면 header Navbar 안에 있는 "search" 부분에서 검색 조건 입력QueryString 넘어오는 searchQuery 변수를 ItemSearchDto 객체의 멤버변수에 초기화
  • QueryString 으로 넘어오는 "page" 변수를 page 파라미터에 넘김
@Controller
@RequiredArgsConstructor // @Autowired로도 쓸 수 있음
public class MainController {

    // @Autowired ->  @RequiredArgsConstructor를 써도 됨 (final 붙여야함)
    private final ItemService itemService;

    @GetMapping("/")
    public String main(ItemSearchDto itemSearchDto, Optional<Integer> page, Model model) {
        Pageable pageable = PageRequest.of(page.isPresent() ? page.get() : 0, 6);
        Page<ItemMainDto> items = itemService.getItemMainDto(itemSearchDto, pageable);

        model.addAttribute("items", items);
        model.addAttribute("itemSearchDto", itemSearchDto);
        model.addAttribute("maxPage", 5);

        return "main";
    }
}

5. Main Page

  • 배너는 BootStrap Carousel 컴포넌트 사용
  • 상품은 BootStrap Card 컴포넌트 사용
  • 상품 이미지를 요청하는 src URL 은 상품 이미지 정보에 담긴 imgUrl 로 지정
<img th:src="${item.imgUrl}" class="card-img-top" th:alt="${item.itemNm}" height="300">

6. 상품 이미지 파일 불러오기 동작 원리

  • application.properties 파일
    • 로컬 내에 파일이 저장된 경로를 uploadPath로 지정
# 리소스 업로드 경로
uploadPath=file:///D:/shop/
  • WebMvcConfigurer 클래스
    • "/images/"로 시작하는 URL 패턴의 요청이 들어오면 uploadPath를 기준으로 파일 탐색
// 이미지 업로드 파일 경로
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

//파일 올리고 이미지 올리고 이럴 때 웹이 로컬을 막 건들면 안되니까 설정 파일을 하나 만들어줌
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    // 이미지/파일을 업로드하는 진짜 경로를 application properties에 uploadPath로 저장해놨는데 그걸 가져오게 하기 위함
    @Value(value = "${uploadPath}")
    private String uploadPath;  // 해당 경로를 사용할 수 있음

    @Override
    // registry를 등록해서 쓸 수 있게 함
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
         registry.addResourceHandler("/images/**") // 접근을 이 주소로 하게 함
                 .addResourceLocations(uploadPath); // 실제로는 여기인데 (위에 처럼함)
    }
}
  • SecurityConfig 클래스
    • "/images/"로 시작하는 URL 패턴의 요청은 모두 허용
// 메모리를 미리 올려놔야 하기 때문에 bean 붙이기
    @Bean
    // http 요청에 대한 보안 설정. 페이지 권한, 로그인 페이지, 로그아웃 메소드 설정 예정
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http.authorizeHttpRequests()  // 인증 여부 확인 -> 스프링 3.0 이하 버전은 authorizeRequests()로 설정
                // 스프링 3.0 이하 버전은 antMatchers(), mvcMatchers(), regexMatchers()으로 사용
 
                .requestMatchers("/", "/member/**", "/item/**", "/images/**").permitAll() // 아무나 페이지에 들어올 수 있고, member, item 밑에 있는 애들은 모두 permit 허용
  • 동작 순서

① src = "images/item/파일명"으로 이미지 파일 요청

② WebConfigurer 에 지정된 핸들러대로 uploadPath를 기준으로 요청 처리

③ "///D:/shop/item/상품명"을 수행하여 일치하는 파일 반환

 

 

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

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

[스프링 부트 쇼핑몰 프로젝트 with JPA] 11. 상품 주문  (1) 2023.10.16
[스프링 부트 쇼핑몰 프로젝트 with JPA] 10. 상세페이지  (0) 2023.10.16
[스프링 부트 쇼핑몰 프로젝트 with JPA] 8-2. [상품 관리] 상품 목록 페이지  (0) 2023.10.16
[스프링 부트 쇼핑몰 프로젝트 with JPA] 8-1. [상품 관리] 상품 목록 조회 Querydsl  (0) 2023.10.16
[스프링 부트 쇼핑몰 프로젝트 with JPA] 7. 상품 수정  (0) 2023.10.16
'Web & Android/스프링 부트 쇼핑몰 프로젝트 with JPA' 카테고리의 다른 글
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 11. 상품 주문
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 10. 상세페이지
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 8-2. [상품 관리] 상품 목록 페이지
  • [스프링 부트 쇼핑몰 프로젝트 with JPA] 8-1. [상품 관리] 상품 목록 조회 Querydsl
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)
  • 블로그 메뉴

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

  • 태그

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

  • hELLO· Designed By정상우.v4.10.0
woojin._.
[스프링 부트 쇼핑몰 프로젝트 with JPA] 9. 메인화면
상단으로

티스토리툴바