쿼리 수정전
<!--페이징을 위한 카운트 쿼리 수정전-->
<select id="selectTotalProductCount" parameterType="map" resultType="int">
SELECT COUNT(*)
FROM PRODUCT P
LEFT JOIN
CATEGORY C ON P.category_seq = C.category_seq
WHERE 1=1
<!-- 카테고리 필터 -->
<if test="category_seq != 0">
AND P.category_seq = #{category_seq}
</if>
<!-- 검색어 필터 -->
<if test="query != null and query != ''">
AND (P.product_serial ILIKE '%' || #{query} || '%')
OR (P.product_name ILIKE '%' || #{query} || '%')
OR (P.product_brand ILIKE '%' || #{query} || '%')
OR (P.product_height ILIKE '%' || #{query} || '%')
OR (P.product_weight ILIKE '%' || #{query} || '%')
OR (P.product_wh ILIKE '%' || #{query} || '%')
OR (P.product_color ILIKE '%' || #{query} || '%')
OR (P.product_features ILIKE '%' || #{query} || '%')
OR (C.category_name ILIKE '%' || #{query} || '%')
</if>
<!-- 브랜드 필터 -->
<if test="product_brand != null and product_brand != ''">
AND P.product_brand = #{product_brand}
</if>
<!-- 가격대 필터 -->
<if test="priceRange != null and priceRange != ''">
AND (
#{priceRange} LIKE '%below10k%' AND P.product_pay < 10000
OR #{priceRange} LIKE '%10kTo20k%' AND P.product_pay BETWEEN 10001 AND 20000
OR #{priceRange} LIKE '%20kTo30k%' AND P.product_pay BETWEEN 20001 AND 30000
OR #{priceRange} LIKE '%30kTo40k%' AND P.product_pay BETWEEN 30001 AND 40000
OR #{priceRange} LIKE '%40kTo50k%' AND P.product_pay BETWEEN 40001 AND 50000
OR #{priceRange} LIKE '%50kTo70k%' AND P.product_pay BETWEEN 50001 AND 70000
OR #{priceRange} LIKE '%80kTo100k%' AND P.product_pay BETWEEN 80001 AND 100000
OR #{priceRange} LIKE '%above100k%' AND P.product_pay > 100000
)
</if>
</select>
쿼리 수정후
<if test="query != null and query != ''">
AND ( (P.product_serial ILIKE '%' || #{query} || '%')
OR (P.product_name ILIKE '%' || #{query} || '%')
OR (P.product_brand ILIKE '%' || #{query} || '%')
OR (P.product_height ILIKE '%' || #{query} || '%')
OR (P.product_weight ILIKE '%' || #{query} || '%')
OR (P.product_wh ILIKE '%' || #{query} || '%')
OR (P.product_color ILIKE '%' || #{query} || '%')
OR (P.product_features ILIKE '%' || #{query} || '%')
OR (C.category_name ILIKE '%' || #{query} || '%')
)
</if>
<!-- 가격대 필터 -->
<if test="priceRange != null">
AND (
#{priceRange} LIKE '%below10k%' AND P.product_pay < 10000
OR #{priceRange} LIKE '%10kTo20k%' AND P.product_pay BETWEEN 10001 AND 20000
OR #{priceRange} LIKE '%20kTo30k%' AND P.product_pay BETWEEN 20001 AND 30000
OR #{priceRange} LIKE '%30kTo40k%' AND P.product_pay BETWEEN 30001 AND 40000
OR #{priceRange} LIKE '%40kTo50k%' AND P.product_pay BETWEEN 40001 AND 50000
OR #{priceRange} LIKE '%50kTo70k%' AND P.product_pay BETWEEN 50001 AND 70000
OR #{priceRange} LIKE '%80kTo100k%' AND P.product_pay BETWEEN 80001 AND 100000
OR #{priceRange} LIKE '%above100k%' AND P.product_pay > 100000
)
</if>
<select id="selectTotalProductCount" parameterType="map" resultType="int">
SELECT COUNT(*)
FROM PRODUCT P
LEFT JOIN
CATEGORY C ON P.category_seq = C.category_seq
WHERE 1=1
<!-- 카테고리 필터 -->
<if test="category_seq != 0 and category_seq != null">
AND P.category_seq = #{category_seq}
</if>
<!-- 검색어 필터 -->
<if test="query != null and query != ''">
AND ( (P.product_serial ILIKE '%' || #{query} || '%')
OR (P.product_name ILIKE '%' || #{query} || '%')
OR (P.product_brand ILIKE '%' || #{query} || '%')
OR (P.product_height ILIKE '%' || #{query} || '%')
OR (P.product_weight ILIKE '%' || #{query} || '%')
OR (P.product_wh ILIKE '%' || #{query} || '%')
OR (P.product_color ILIKE '%' || #{query} || '%')
OR (P.product_features ILIKE '%' || #{query} || '%')
OR (C.category_name ILIKE '%' || #{query} || '%')
)</if>
<!-- 브랜드 필터 -->
<if test="product_brand != null and product_brand != ''">
AND P.product_brand = #{product_brand}
</if>
<!-- 가격대 필터 -->
<if test="priceRange != null">
AND (
#{priceRange} LIKE '%below10k%' AND P.product_pay < 10000
OR #{priceRange} LIKE '%10kTo20k%' AND P.product_pay BETWEEN 10001 AND 20000
OR #{priceRange} LIKE '%20kTo30k%' AND P.product_pay BETWEEN 20001 AND 30000
OR #{priceRange} LIKE '%30kTo40k%' AND P.product_pay BETWEEN 30001 AND 40000
OR #{priceRange} LIKE '%40kTo50k%' AND P.product_pay BETWEEN 40001 AND 50000
OR #{priceRange} LIKE '%50kTo70k%' AND P.product_pay BETWEEN 50001 AND 70000
OR #{priceRange} LIKE '%80kTo100k%' AND P.product_pay BETWEEN 80001 AND 100000
OR #{priceRange} LIKE '%above100k%' AND P.product_pay > 100000
)
</if>
</select>
</mapper>
최초 기능 설계시
검색기능과 필터/정렬 기능을 각각 분리하여 SQL 문을설계 진행 -> 기능을 구현후 테스트 진행시 결과조건은 동일하고
category_seq 와 query(검색어) 유무에 따른 결과 분리
- currentPage:
- 설명: param.page가 비어 있으면(예: 첫 진입 시), 기본값으로 1을 설정합니다.
- 결과: 현재 페이지 번호.
<c:set var="currentPage" value="${empty param.page ? 1 : param.page}" />
- totalPages:
- 설명: 전체 페이지 수를 totalPages 변수에 저장합니다. 서버에서 전달된 값을 사용.
<c:set var="totalPages" value="${totalPages}" />
이전 버튼
<li class="page-item ${currentPage == 1 ? 'disabled' : ''}">
<a class="page-link mx-1" href="javascript:void(0);" aria-label="Previous" data-page="${currentPage > 1 ? currentPage - 1 : 1}">
<i class="feather-icon icon-chevron-left"></i>
</a>
</li>
- 클래스 계산:
- currentPage == 1이면 "disabled" 클래스를 추가해 비활성화.
- 데이터 속성 계산:
- data-page: currentPage가 1보다 크면 currentPage - 1(이전 페이지)을 설정.
그렇지 않으면 1을 유지.
페이지 번호 계산
<c:forEach var="i" begin="${currentPage - 2 > 1 ? currentPage - 2 : 1}" end="${currentPage + 2 < totalPages ? currentPage + 2 : totalPages}">
<li class="page-item ${currentPage == i ? 'active' : ''}">
<a class="page-link mx-1" href="javascript:void(0);" data-page="${i}">${i}</a>
</li>
</c:forEach>
- begin 시작 값:
- 설명: 현재 페이지에서 왼쪽으로 최대 2개 표시.
- 만약 (currentPage - 2)가 1보다 작으면 1로 시작.
${currentPage - 2 > 1 ? currentPage - 2 : 1}
- end 종료 값:
- 설명: 현재 페이지에서 오른쪽으로 최대 2개 표시.
- 만약 (currentPage + 2)가 totalPages보다 크면 마지막 페이지(totalPages)를 표시
${currentPage + 2 < totalPages ? currentPage + 2 : totalPages}
- 활성화 클래스:
- 현재 페이지(currentPage)와 반복 변수(i)가 같으면 active 클래스를 추가해 시각적으로 강조
class="${currentPage == i ? 'active' : ''}"
'...' 표시
<li class="page-item ${currentPage + 2 < totalPages ? '' : 'd-none'}">
<a class="page-link mx-1" href="#">...</a>
</li>
- currentPage + 2 < totalPages이면 ... 표시.
(즉, 현재 페이지 기준으로 오른쪽 2칸 이후에 더 많은 페이지가 있을 때만 표시.)
마지막 페이지 버튼
<li class="page-item ${currentPage == totalPages ? 'disabled' : ''}">
<a class="page-link mx-1" href="javascript:void(0);" aria-label="Next" data-page="${currentPage < totalPages ? currentPage + 1 : totalPages}">
<i class="feather-icon icon-chevron-right"></i>
</a>
</li>
- 클래스 계산:
- currentPage == totalPages이면 "disabled" 클래스를 추가해 비활성화.
- 데이터 속성 계산:
- data-page: currentPage가 totalPages보다 작으면 currentPage + 1(다음 페이지)을 설정.
그렇지 않으면 마지막 페이지(totalPages)를 유지.