public ProductDTO selectProductByProdNo(String prodNo) {
Optional<Product> optProduct = productRepository.findByProdNo(prodNo);
if (optProduct.isPresent()) {
Product product = optProduct.get();
ProductDTO productDTO = modelMapper.map(product, ProductDTO.class);
productDTO = OptionSplit(productDTO);
return productDTO;
}
return null;
}
기술 설명
- selectProductByProdNo(String prodNo):
productRepository.findByProdNo(prodNo)을 호출하여prodNo에 해당하는Product엔티티 조회.- 엔티티가 존재하면
ModelMapper로Product→ProductDTO로 매핑.- 매핑된
ProductDTO를OptionSplit메서드로 전달하여 옵션 정보를 배열 형태로 분리 후 반환.- 조회 결과가 없으면
null반환.
public ProductDTO OptionSplit(ProductDTO productDTO) {
String prodNo = productDTO.getProdNo();
Product product = productRepository.findById(prodNo).orElse(null);
ProductDTO productDTO1 = modelMapper.map(product, ProductDTO.class);
String[] option = new String[6];
String[][] str = new String[6][10];
if (productDTO1.getProductDetail() != null) {
// 첫 번째 옵션
if (productDTO1.getProductDetail().getOpt1() != null) {
option[0] = productDTO1.getProductDetail().getOpt1();
String[] optList = productDTO1.getProductDetail().getOpt1Cont().split(",");
for (int i = 0; i < optList.length; i++) {
str[0][i] = optList[i];
}
}
// 두 번째 옵션
if (productDTO1.getProductDetail().getOpt2() != null) {
option[1] = productDTO1.getProductDetail().getOpt2();
String[] optList = productDTO1.getProductDetail().getOpt2Cont().split(",");
for (int i = 0; i < optList.length; i++) {
str[1][i] = optList[i];
}
}
// 세 번째 옵션
if (productDTO1.getProductDetail().getOpt3() != null) {
option[2] = productDTO1.getProductDetail().getOpt3();
String[] optList = productDTO1.getProductDetail().getOpt3Cont().split(",");
for (int i = 0; i < optList.length; i++) {
str[2][i] = optList[i];
}
}
// 네 번째 옵션
if (productDTO1.getProductDetail().getOpt4() != null) {
option[3] = productDTO1.getProductDetail().getOpt4();
String[] optList = productDTO1.getProductDetail().getOpt4Cont().split(",");
for (int i = 0; i < optList.length; i++) {
str[3][i] = optList[i];
}
}
// 다섯 번째 옵션
if (productDTO1.getProductDetail().getOpt5() != null) {
option[4] = productDTO1.getProductDetail().getOpt5();
String[] optList = productDTO1.getProductDetail().getOpt5Cont().split(",");
for (int i = 0; i < optList.length; i++) {
str[4][i] = optList[i];
}
}
// 여섯 번째 옵션
if (productDTO1.getProductDetail().getOpt6() != null) {
option[5] = productDTO1.getProductDetail().getOpt6();
String[] optList = productDTO1.getProductDetail().getOpt6Cont().split(",");
for (int i = 0; i < optList.length; i++) {
str[5][i] = optList[i];
}
}
productDTO.setOption(option);
productDTO.setOptions(str);
return productDTO;
}
return productDTO;
}
기술 설명
- OptionSplit(ProductDTO productDTO):
- 입력받은
ProductDTO내부의ProductDetail에서 최대 6개의 옵션(opt1~opt6)과 대응하는 옵션 목록(optXCont)을 분리.String[] option = new String[6]배열에 각각 옵션명 저장.String[][] str = new String[6][10]배열에 각 옵션명에 대한 콤마로 구분된 옵션값을split(",")하여 2차원 배열로 저장.- 옵션 값이 존재하지 않으면 해당 인덱스는
null상태로 유지.- 최종 결과로
productDTO.setOption(option)및productDTO.setOptions(str)를 호출하여 옵션명 배열과 옵션값 배열을 DTO에 설정 후 반환.
@Cacheable(value = "slide-banners", key = "#cate")
public List<BannerDTO> findBanner(String cate) {
List<Banner> bannerList = bannerRepository.findBannerByCate(cate);
List<BannerDTO> bannerDTOList = new ArrayList<>();
for (Banner banner : bannerList) {
bannerDTOList.add(modelMapper.map(banner, BannerDTO.class));
}
return bannerDTOList;
}
기술 설명
- @Cacheable(value = "slide-banners", key = "#cate"):
findBanner메서드 호출 결과를'slide-banners::카테고리'키로 캐싱.- 동일한
cate인자로 재요청 시 DB 조회를 생략하고 캐시된 결과 반환.- findBanner(String cate):
bannerRepository.findBannerByCate(cate)호출하여 해당 카테고리(cate)의Banner엔티티 목록 조회.ModelMapper로 각Banner→BannerDTO로 매핑하여List<BannerDTO>반환.
public BannerDTO randomBanner(List<BannerDTO> banners) {
List<BannerDTO> activeBanners = new ArrayList<>();
LocalDateTime now = LocalDateTime.now();
for (BannerDTO banner : banners) {
LocalDateTime startDateTime = LocalDateTime.of(banner.getStartDay(), banner.getStartTime());
LocalDateTime endDateTime = LocalDateTime.of(banner.getEndDay(), banner.getEndTime());
if (startDateTime.isBefore(now) && endDateTime.isAfter(now)) {
activeBanners.add(banner);
}
}
if (activeBanners.isEmpty()) {
return null;
} else {
int size = banners.size();
int random = (int) (Math.random() * size);
return activeBanners.get(random);
}
}
기술 설명
- randomBanner(List banners):
- 현재 시각(
now = LocalDateTime.now())을 기준으로banners목록을 순회.- 각
BannerDTO의startDay,startTime,endDay,endTime을LocalDateTime으로 변환 후 비교:
startDateTime.isBefore(now) && endDateTime.isAfter(now)인 경우에만 활성화 광고로 간주하여activeBanners목록에 추가.- 활성화 광고가 하나도 없으면
null반환.- 그렇지 않으면
Math.random() * size를 이용해 활성화 광고 목록에서 랜덤 인덱스를 선택 후 해당BannerDTO반환.
public PageResponseDTO selectAllForReview(PageRequestDTO pageRequestDTO) {
Pageable pageable = pageRequestDTO.getPageable("prodNo");
Page<Tuple> pageReview = reviewRepository.selectAllForList(pageRequestDTO, pageable);
List<ReviewDTO> reviewDTOList = pageReview.getContent().stream().map(tuple -> {
Review review = tuple.get(0, Review.class);
String uid = tuple.get(1, String.class);
ReviewDTO reviewDTO = modelMapper.map(review, ReviewDTO.class);
reviewDTO.setUid(uid);
return reviewDTO;
}).toList();
int total = (int) pageReview.getTotalElements();
double setAvgRate = calculateAvgRate(new PageResponseDTO<>(pageRequestDTO, reviewDTOList, total));
PageResponseDTO<ReviewDTO> responseDTO = PageResponseDTO.<ReviewDTO>builder()
.pageRequestDTO(pageRequestDTO)
.dtoList(reviewDTOList)
.total(total)
.build();
responseDTO.setAvgRate(setAvgRate);
return responseDTO;
}
기술 설명
- selectAllForReview(PageRequestDTO pageRequestDTO):
- 페이징 설정:
pageRequestDTO.getPageable("prodNo")호출하여prodNo기준 페이지 요청 정보(Pageable) 생성.- QueryDSL 조회:
reviewRepository.selectAllForList(pageRequestDTO, pageable)로Page<Tuple>형태의 페이징 결과 반환.
Tuple에는(Review 엔티티, 작성자 uid 문자열)이 순서대로 포함.- DTO 변환:
pageReview.getContent().stream().map(tuple -> { ... }).toList()로 각Tuple을 분해.Review엔티티와uid를 꺼내ReviewDTO로 매핑 후reviewDTO.setUid(uid)설정.- 총 리뷰 개수:
pageReview.getTotalElements()를 정수로 변환하여total.- 평균 평점 계산:
calculateAvgRate(new PageResponseDTO<>(pageRequestDTO, reviewDTOList, total))호출하여 평균 평점(double) 계산.- 응답 DTO 생성:
PageResponseDTO.<ReviewDTO>builder()빌더 생성.pageRequestDTO,dtoList = reviewDTOList,total설정.responseDTO.setAvgRate(setAvgRate)로 평균 평점을 포함시켜 최종PageResponseDTO<ReviewDTO>반환.
public double calculateAvgRate(PageResponseDTO reviewPageResponseDTO) {
if (reviewPageResponseDTO != null && reviewPageResponseDTO.getDtoList() != null && !reviewPageResponseDTO.getDtoList().isEmpty()) {
double avgRating = 0;
List<ReviewDTO> dtoList = reviewPageResponseDTO.getDtoList();
for (ReviewDTO review : dtoList) {
avgRating += review.getRating().doubleValue();
}
double average = avgRating / dtoList.size();
return Math.round(average * 10) / 10.0; // 소수점 첫째 자리까지 반올림
}
return 0.0;
}
기술 설명
- calculateAvgRate(PageResponseDTO reviewPageResponseDTO):
reviewPageResponseDTO가null이 아니고dtoList가 비어 있지 않은 경우에만 계산 수행.avgRating변수에ReviewDTO.getRating()값을 모두 더함.- 전체 리뷰 개수(
dtoList.size())로 나눠 평균(average) 계산.Math.round(average * 10) / 10.0으로 소수점 첫째 자리까지 반올림 후 반환.- 목록이 없으면
0.0반환.
public PageResponseDTO selectAllForQna(PageRequestDTO pageRequestDTO) {
Pageable pageable = pageRequestDTO.getPageable("prodNo");
Page<Tuple> pageInquiry = inquiryRepository.selectAllForList(pageRequestDTO, pageable);
List<InquiryDTO> inquiryDTOList = pageInquiry.getContent().stream().map(tuple -> {
Inquiry inquiry = tuple.get(0, Inquiry.class);
String uid = tuple.get(1, String.class);
InquiryDTO inquiryDTO = modelMapper.map(inquiry, InquiryDTO.class);
inquiryDTO.setUid(uid);
return inquiryDTO;
}).toList();
int total = (int) pageInquiry.getTotalElements();
return PageResponseDTO.<InquiryDTO>builder()
.pageRequestDTO(pageRequestDTO)
.dtoList(inquiryDTOList)
.total(total)
.build();
}