보라코딩

Day108_230601_페이징처리... 하........... 본문

코딩/Spring

Day108_230601_페이징처리... 하...........

new 보라 2023. 6. 1. 16:46

와 해결했다... 

너무 감동이라 빨간색으로 씀

<![CDATA[    ...... ]]

페이징 처리를 위해 <와 > 표시가 들어가서 저 코드를 써서 문자화해주었는데

저 코드를 맨위에 맨 아래에 넣으니

<if....>까지 문자화되어서 안되었던 것....

결국 빨리 닫아버리고

if와 choose를 쓰니 된다 ㅠㅠㅠㅠㅠㅠㅠㅠㅠ

 

 

 

====================================================

 

 

 

맛집 메인페이지에 페이징을 넣으려고 했는데

생각보다 매우 쉽지 않다.

 

왜냐면 난 이미 메인 페이지에

 

join해서 별점 평균도 가져오고, 메인 맛집 정보도 가져오면서

별점순/인기순/거리순/FOODSTYLE 정렬을 가능하게 해둔 상태로

페이징과 검색처리까지 넣으려니...

계속 문제가 생겼다 ㅠㅠㅠ

 

근데 더 짜증나는건

분명 SQL문은 문제가 없는데

스프링에서 문제생김 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

 

여튼...

페이징만 우선 구현은 했는데

그랬더니 별점순/인기순/거리순/FOODSTYLE 정렬이 안됨.........

하.........

페이징 먼저 올리자!!

 

 

 

 

 

 

 

list.html

 



<!--페이징시작!!!!-->
<!-- 이전 버튼 -->
<th:block th:if="${pageMaker.prev}">
<li class="pageMaker_btn prev">
<a href="javascript:void(0)" th:onclick="movePage([[ ${#request.requestURI} ]], [[ ${pageMaker.cri.makeQueryString(pageMaker.pageStart - 1)} ]])">이전</a>
</li>
</th:block>

<!-- 페이지 번호 -->
<th:block th:with="pageMaker = ${pageMaker}">
<th:block th:each="num : *{#numbers.sequence(pageMaker.pageStart, pageMaker.pageEnd)}">
<li class="pageMaker_btn" th:classappend="${pageMaker.cri.pageNum == num} ? 'active' : ''">
<a href="javascript:void(0)" th:text="${num}" th:onclick="movePage([[ ${#request.requestURI} ]],[[ ${pageMaker.cri.makeQueryString(num)} ]])"></a>
</li>
</th:block>
</th:block>


<!-- 다음 버튼 -->
<th:block th:if="${pageMaker.next}">
<li class="pageMaker_btn next">
<a href="javascript:void(0)" th:onclick="movePage( [[ ${#request.requestURI} ]], [[ ${pageMaker.cri.makeQueryString(pageMaker.pageEnd + 1)} ]])">다음</a>
</li>
</th:block>

<p th:text="${pageMaker}"></p>

</main>


<script>

/* ![CDATA[ */
function movePage(uri, queryString) {
console.log(uri);
console.log(queryString);

location.href = uri + queryString;
}
/* ]]*/
</script>

 

참고로 css는

.pagination-container {
margin: 0px auto;
text-align: center;
}

.pagination-item {
display: inline-block;
margin: 0 5px;
}

.pagination-item a {
position: relative;
display: inline-block;
color: #2c3e50;
text-decoration: none;
font-size: 1.2rem;
padding: 8px 16px 10px;
transition: all 0.2s;
}

.pagination-item a:before {
z-index: -1;
position: absolute;
height: 100%;
width: 100%;
content: "";
top: 0;
left: 0;
background-color: pink;
border-radius: 24px;
transform: scale(0);
transition: all 0.2s;
}

.pagination-item a:hover,
.pagination-item.active a {
color: #fff;
}

.pagination-item a:hover:before,
.pagination-item.active a:before {
transform: scale(1);
}

.pagination-item.prev,
.pagination-item.next {
margin: 0 10px;
}

 

 

 

 

 

Controller
@GetMapping("/list")
public void get(Model model
, @RequestParam(value="cuisineSelect",required = false) String cuisineSelect
, @RequestParam(value="storeStar",required = false) String storeStar
, @RequestParam(value="storeCount",required = false) String storeCount
, @RequestParam(value="storeDistance",required = false) String storeDistance
, Criteria cri
){

if(cuisineSelect == null){
cuisineSelect = "없음";
}

if(storeStar == null){
storeStar = "없음";
}

if(storeCount == null){
storeCount = "없음";
}

if(storeDistance == null){
storeDistance = "없음";
}

Map<String,Object> orderMap = new HashMap<>();
orderMap.put("cuisineSelect", cuisineSelect);
orderMap.put("storeStar", storeStar);
orderMap.put("storeCount", storeCount);
orderMap.put("storeDistance", storeDistance);
orderMap.put("cri", cri);


log.info("orderMap : " + orderMap);

List<StoreVO> storeVO = service.store_getList(orderMap);
model.addAttribute("storeList", storeVO);

/*페이징*/
int total = service.store_totalCnt(cri);
PageDTO pageMaker = new PageDTO(cri, total);
model.addAttribute("pageMaker", pageMaker);

log.info("total : " + total);
log.info("new PageDTO(cri, total) : " + pageMaker);

}

 

 

 

 

 

 

Service
public List<StoreVO> store_getList(Map<String, Object> orderMap) {

//List<StoreVO> storeList = mapper.store_getList();
List<StoreVO> storeList = mapper.store_getList_withStar_withPaging(orderMap);

return storeList;
}

public int store_totalCnt(Criteria cri) {

return mapper.getTotalCount(cri);
}

 

 

 

 

 

mapper
List<StoreVO> store_getList_withStar_withPaging(Map<String,Object> orderMap);
int getTotalCount(Criteria cri);

 

 

 

 

mapper.xml

 

<!-- 메인 맛집 전체보기 화면에서 별점과 같이 받기 -->
<select id="store_getList_withStar_withPaging" resultMap="storeStarResultMap"
parameterType="Map">
<![CDATA[

SELECT *
FROM (
SELECT s.store_idx, s.user_idx, s.store_name, s.category1, s.store_address,
s.store_lati, s.store_longi, s.phone_number, s.store_count, s.filename, s.distance,
avg_star.STORE_STAR,
ROWNUM AS RNUM
FROM (
SELECT store_idx, user_idx, store_name, category1, store_address,
store_lati, store_longi, phone_number, store_count, filename, distance
FROM STORE
ORDER BY store_idx ASC
) s
LEFT OUTER JOIN (
SELECT store_idx, ROUND(AVG(store_star), 1) AS STORE_STAR
FROM STAR
GROUP BY store_idx

) avg_star ON s.store_idx = avg_star.store_idx
WHERE ROWNUM <= #{cri.pageNum} * #{cri.amount}
ORDER BY store_idx ASC
)
WHERE RNUM > ((#{cri.pageNum} - 1) * #{cri.amount})

]]>


<if test="cuisineSelect != '없음'">
and category1 = #{cuisineSelect}
</if>

<choose>
<when test="storeStar != '없음'">
order by STORE_STAR DESC NULLS LAST
</when>
<when test="storeCount != '없음'">
order by store_count DESC NULLS LAST
</when>
<when test="storeDistance != '없음'">
order by distance ASC NULLS LAST
</when>
<otherwise>
ORDER BY store_idx ASC
</otherwise>

</choose>



</select>

 

<!--페이징 처리시 전체 글수 확인-->
<select id="getTotalCount" parameterType="Criteria"
resultType="integer">
SELECT count(*)
FROM store
</select>

 

 

 

 

 

Criteria

 

package com.tastemate.domain.paging;

import lombok.Data;
import org.apache.ibatis.type.Alias;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

@Data
@Alias("Criteria")
public class Criteria {

/* 현재 페이지 번호 */
private int pageNum;

/* 페이지 표시 개수 */
private int amount;

/* 페이지 skip */
private int skip;

/* 검색 타입 */
private String type;

/* 검색 키워드 */
private String keyword;

/* Criteria 생성자 */
public Criteria(int pageNum, int amount) {
this.pageNum = pageNum;
this.amount = amount;
this.skip = (pageNum - 1) * amount;
}

/* Criteria 기본 생성자 */
public Criteria() {
this(1, 4);
}

/* 검색 타입 데이터 배열 변환 */
public String[] getTypeArr() {
return type == null ? new String[]{} : type.split("");
}

public void setPageNum(int pageNum) {
this.pageNum = pageNum;
this.skip = (pageNum - 1) * this.amount;
}

public void setAmount(int amount) {
this.amount = amount;
this.skip = (this.pageNum - 1) * amount;
}

public String makeQueryString(int pageNum) {

UriComponents uriComponents = UriComponentsBuilder.newInstance()
.queryParam("pageNum", pageNum)
.queryParam("amount", amount)
.queryParam("searchType", type)
.queryParam("keyword", keyword)
.build()
.encode();

return uriComponents.toUriString();
}
}

 

 

 

 

 

PageDTO
package com.tastemate.domain.paging;

import lombok.Data;
import lombok.Getter;
import lombok.ToString;

@Data
public class PageDTO {

/* 페이지 시작 번호 */
private int pageStart;

/* 페이지 끝 번호 */
private int pageEnd;

/* 이전, 다음 버튼 존재 유무 */
private boolean next, prev;

/* 행 전체 개수 */
private int total;

/* 현재페이지 번호(pageNum), 행 표시 수(amount), 검색 키워드(keyword), 검색 종류(type)*/
private Criteria cri;

/* 생성자(클래스 호출 시 각 변수 값 초기화 */
public PageDTO(Criteria cri, int total) {

/* cri, total 초기화 */
this.cri = cri;
this.total = total;

/* 페이지 끝 번호 */
this.pageEnd = (int) (Math.ceil(cri.getPageNum() / 10.0)) * 10;

/* 페이지 시작 번호 */
this.pageStart = this.pageEnd - 9;

/* 전체 마지막 페이지 번호 */
int realEnd = (int) (Math.ceil(total * 1.0 / cri.getAmount()));

/* 페이지 끝 번호 유효성 체크 */
if (realEnd < pageEnd) {
this.pageEnd = realEnd;
}

/* 이전 버튼 값 초기화 */
this.prev = this.pageStart > 1;

/* 다음 버튼 값 초기화 */
this.next = this.pageEnd < realEnd;
}
}

 

 

 

 

 

스프링부트 페이징처리 + 별점순/인기순/거리순 + join까지.. (tistory.com)

 

스프링부트 페이징처리 + 별점순/인기순/거리순 + join까지..

페이징처리가 되면 별점순 인기순 거리순이 안되고 반대가 되면 페이징이 안되는 고통에서 벗어났다! 드디어 해결했다...! SQL문과 스프링부트 제대로 공부한 느낌이긴 함! 며칠 걸렸네.... 뿌듯

boracoding.tistory.com