<section class="studyCategory">
<div class="studyCategory__container max-container">
<div class="studyCategory__left">
<p>카테고리</p>
<div class="studyCategory__left__list">
<a href="studyList.do?cp=1&sc_idx=0" class="cate ${param.sc_idx=='0'?'active':''}">전체</a>
<a href="studyList.do?cp=1&sc_idx=1" class="cate ${param.sc_idx=='1'?'active':''}">코딩</a>
<a href="studyList.do?cp=1&sc_idx=2" class="cate ${param.sc_idx=='2'?'active':''}">언어</a>
<a href="studyList.do?cp=1&sc_idx=3" class="cate ${param.sc_idx=='3'?'active':''}">학업</a>
<a href="studyList.do?cp=1&sc_idx=4" class="cate ${param.sc_idx=='4'?'active':''}">자격증</a>
<a href="studyList.do?cp=1&sc_idx=5" class="cate ${param.sc_idx=='5'?'active':''}">취업</a>
</div>
<p>총 <span>${studyListCount}</span>개의 스터디</p>
</div>
</div>
</section>
<section class="studyGrid">
<c:if test="${!empty requestScope.studyList}">
<c:forEach var="dto" items="${requestScope.studyList}">
<article class="studyCard">
<div class="studyCard__thumb">
<img src="/histudy/study-img/${!empty dto.study_upload_img ? dto.study_upload_img : 'groupStudy.png'}" alt="스터디 이미지">
</div>
<div class="studyCard__content">
<div class="studyCard__tags">
<span class="tag tag--language">${dto.sc_name}</span>
</div>
<h3 class="studyCard__title">${dto.study_title}</h3>
<div class="studyCard__rating">
<div class="stars">
★★★★☆ <span style="color:black; font-weight:bold">4.9 (24)</span>
</div>
</div>
<ul class="studyCard__meta">
<li><img src="/histudy/main-img/user.png">${dto.user_name}</li>
<li><img src="/histudy/main-img/personnel.png">${dto.study_current_members }/${dto.study_max_members}명</li>
<li><img src="/histudy/main-img/clock.png">마감일 - ${dto.study_end_date.substring(0, 10)}</li>
<li><img src="/histudy/main-img/location.png">${empty dto.study_addr?'장소가 지정되지 않았어요':dto.study_addr }</li>
</ul>
</div>
</article>
</c:forEach>
</c:if>
<c:if test="${empty requestScope.studyList}">
<div id="notStudy">
<h2>개설된 스터디가 없습니다.</h2>
</div>
</c:if>
</section>
<div class="paging">
${pageStr}
</div>
@GetMapping("/studyList.do")
public ModelAndView studyList(
@RequestParam(value="cp", defaultValue="1")int cp,
@RequestParam(value="sc_idx", defaultValue="0")Integer sc_idx) {
// int로 받을 경우에 없다면? 0이 들어옴
// Integer로 받는다면 ? 래퍼클래스이기 때문에 null 비교 가능
int listSize = 9;
int pageSize = 5;
int totalCnt = 0;
String pagename = "studyList.do";
int start_num = (cp-1)*listSize+1;
int end_num = cp*listSize;
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("start_num", start_num);
map.put("end_num", end_num);
if(sc_idx == 0) {
sc_idx = null;
totalCnt = ss.studyTotalCnt(sc_idx);
}else {
totalCnt = ss.studyTotalCnt(sc_idx);
}
map.put("sc_idx", sc_idx);
String pageStr = com.histudy.page.PagingModule.makePage(cp, listSize, pageSize, totalCnt, pagename, sc_idx);
List<StudyDTO> lists = ss.getStudyList(map);
ModelAndView mav = new ModelAndView();
mav.addObject("studyList", lists);
mav.addObject("studyListCount", lists.size());
mav.addObject("pageStr", pageStr);
mav.setViewName("study/studyList");
return mav;
}
<select id="selectStudyList" parameterType="map" resultType="com.histudy.study.model.StudyDTO">
SELECT *
FROM
(SELECT rownum as rnum, a.*
FROM
(
SELECT study.*, usertb.user_name, study_category.sc_name
FROM study JOIN usertb ON study.user_idx=usertb.user_idx JOIN study_category ON study_category.sc_idx = study.sc_idx
<if test="sc_idx != null">
WHERE study_category.sc_idx=#{sc_idx}
</if>
ORDER BY study_idx desc
) a ) b
WHERE rnum between #{start_num} and #{end_num}
</select>
<select id="studyTotalCnt" parameterType="Integer" resultType="Integer">
SELECT count(*)
FROM study
<if test="sc_idx != null">
WHERE sc_idx=#{sc_idx}
</if>
</select>
<select id="studyTotalCnt" parameterType="Integer" resultType="Integer">
SELECT count(*)
FROM study
<if test="sc_idx != null">
WHERE sc_idx=#{sc_idx}
</if>
</select>
처음에는 기본적인 페이징 모듈과 sql 쿼리를 이용해서 구현을 했다. 사용자가 보는 화면에 필요한 요소들은 테이블 JOIN문을 통해 가져왔다.
그 이후 사용자가 카테고리를 클릭 했을 때 해당 카테고리만 조회해야 했다.
JSP에서 사용자가 카테고리를 클릭하면 나는 <a> 태그를 이용해 파라미터로 sc_idx (카테고리 번호)를 넘겨줬다.
이때도 처음에는 sc_idx를 int 타입으로 받았는데 생각을 해보니.. MyBatis 쿼리를 활용 할 수 있으니 null 처리를 할 수 있게 Integer 타입으로 변경 했다.
@RequestParam을 이용해서 sc_idx값을 받는데 만약 값이 안 넘어왔을 때 defaultValue=”0”으로 세팅 해줬다.
만약 사용자가 카테고리를 클릭 했다면 sc_idx는 0이 아닐 것이고, 스터디 리스트 페이지에 처음 접속 했거나 카테고리를 클릭 하지 않았다면 sc_idx는 0이 될 것이다.
이 때 만약 sc_idx가 0이라면 sc_idx 에 null을 대입했다. 이유는..?
우선, 사용자가 카테고리를 선택하면 그거에 맞는 페이징이 되어야 되는데 SQL 쿼리를 두 개 만드는 것 보다 하나의 SQL에서 두 가지의 동작을 할 수 있게 MyBatis 활용을 해야겠다고 생각했다.
즉, sc_idx가 null 이라면 테이블에 있는 총 데이터 수를 가져오게 만들고,
null이 아니라면 WHERE sc_idx = #{sc_idx} 이 조건절을 추가하여 해당 카테고리의 총 데이터 수를 가져오게 만들었다.
이렇게 하면 상황에 맞는 페이징이 정상적으로 이루어진다.