보라코딩
Day108_230601_페이징처리... 하........... 본문
와 해결했다...
너무 감동이라 빨간색으로 씀
페이징 처리를 위해 <와 > 표시가 들어가서 저 코드를 써서 문자화해주었는데
저 코드를 맨위에 맨 아래에 넣으니
<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는
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
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
//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
int getTotalCount(Criteria cri);
mapper.xml
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
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
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
'코딩 > Spring' 카테고리의 다른 글
하트 이모티콘 (+ 부트스트랩) (0) | 2023.06.02 |
---|---|
부트스트랩 carousel (회전목마, 슬라이드쇼) (0) | 2023.06.02 |
별점 평가하는 화면 (부트스트랩 + 보라색 사용ㅎㅎ) (0) | 2023.05.31 |
거리순 기능 구현하기 (자바 거리 계산) (0) | 2023.05.31 |
맛집 스타일별 정렬하기 / 별점순 / 인기순 / 거리순 구현하기 (0) | 2023.05.31 |