본문 바로가기
카테고리 없음

게시판 구현 / 4. 게시판 디테일(클릭 시 조회수 올리기)

by maverick11471 2024. 7. 19.

 

자유게시판과 공지사항에 있는 조회수를 카운트하는 방법에 대해 알아보자.

 

 

[요약]

 - BoardController를 수정하여 클릭 시 free-detail.jsp 로 넘어간 후 조회수가 1 오를 수 있도록 조치

 - 조회수는 올라가지만 새로고침할 때 마다 조회수가 올라가는 것에 대해 조치

  * 새로 Controller 작성

  * redirect 이용


[freeboard-mapper 수정]

 - id에 따른 자유게시판 조회수 증가

<update id="updateCnt" parameterType="int">
    UPDATE FREEBOARD
        SET
            CNT = CNT + 1
        WHERE ID = #{id}
</update>

 

[freeboardDao 수정]

public void updateCnt(int id) {
    mybatis.update("FreeBoardDao.updateCnt", id);
}

 

[Service 수정]

void updateCnt(int id);

 

[serviceImpl 수정]

@Override
public void updateCnt(int id) {
    freeBoardDao.updateCnt(id);
}

 

[controller 수정]

 - /free-detail.do url 안에다 boardService.updateCnt(boardDto.getId()); 를 포함시키면

   새로고침 할 때마다 조회수가 올라가게 된다.

    @GetMapping("/free-detail.do")
    public String freeDetailView(BoardDto boardDto, Model model) {
        boardService = applicationContext.getBean("freeBoardServiceImpl", BoardService.class);
        // 아래 줄주석처리한 부분 때문에 새로고침을 해도 조회수가 올라감
        // boardService.updateCnt(boardDto.getId());
        model.addAttribute("freeBoard", boardService.getBoard(boardDto.getId()));

        return "board/free-detail";
    }

 

 - (참고) getBoard 메서드(freeBoardDao)

public BoardDto getBoard(int id) {
    System.out.println("FreeBoardDao의 getBoard 메소드 실행");

    BoardDto boardDto = new BoardDto();

    // SqlSessionTemplate의 selectOne메소드 사용
    boardDto = mybatis.selectOne("FreeBoardDao.getBoard", id);

    System.out.println("FreeBoardDao의 getBoard 메소드 실행 종료");
    return boardDto;
}

- (참고) mapper(getBoard)

<select id="getBoard" parameterType="int" resultType="board">
    SELECT F.ID
         , F.TITLE
         , F.CONTENT
         , F.WRITER_ID
         , M.NICKNAME
         , F.REGDATE
         , F.MODDATE
         , F.CNT
        FROM FREEBOARD F
        JOIN MEMBER M
          ON F.WRITER_ID = M.ID
        WHERE F.ID = #{id}
</select>

 


 

(문제점) 새로고침을 해도 조회수가 올라간다.

 

계속해서 free-detail 페이지를 요청하기 때문이다.

 

그래서 controller 에서 조회수만 별도로 기능을 분리하여 클릭했을때만 조회수가 올라가도록 한다.

 

[controller 수정]

@GetMapping("update-cnt.do")
public String updateCnt(BoardDto boardDto) {
    // Type에 따라 자유게시판과 공지사항 구분
	if(boardDto.getType().equals("free")) {
        boardService = applicationContext.getBean("freeBoardServiceImpl", BoardService.class);
    } else {
        boardService = applicationContext.getBean("noticeServiceImpl", BoardService.class);
    }

    boardService.updateCnt(boardDto.getId());

	// 주소창에 id값이 나오도록 Dto에서 id값을 받아와서 jsp페이지로 이동
    // Type에 따라 자유게시판과 공지사항 구분
    if(boardDto.getType().equals("free")) {
        return "redirect:/board/free-detail.do?id=" + boardDto.getId();
    } else {
        return "redirect:/board/notice-detail.do?id=" + boardDto.getId();
    }
}

 

[free-list.jsp 수정]

<tbody class="table-group-divider">
	// jstl c:forEach 방식으로 list에서 하나씩 꺼내오는 방식
    // var="freeboard"는 list에서 꺼내온 하나의 객체로 이름은 상관없다.
    <c:forEach items="${freeBoardList}" var="freeBoard">
    						// 클릭시 id가 자유게시판 id를 갖고있고
                            // type=free인 /board/upde-cnt.do 주소로 이동
        <tr class="board-tr" onclick="location.href='/board/update-cnt.do?id=${freeBoard.id}&type=free'">
            <td>${freeBoard.id}</td>
            <td>${freeBoard.title}</td>
            <td>${freeBoard.nickname}</td>
            <td>
                <javatime:format value="${freeBoard.regdate}" pattern="yyyy-MM-dd"/>
            </td>
            <td>${freeBoard.cnt}</td>
        </tr>
    </c:forEach>
</tbody>


결과로 아래 사진과 같이 id가 표현되는데 이 때 주의해야 할 점이 있다.

 

바로

location.href

 

이것이다.

 

이 코드의 특징은

 

1. 고정값만 있을경우 url 주소에 일반값도 포함

2. 변수를 활용하여 url 주소 구성 시 변수값만 포함

 

예를들어

 

가. location.href = '/board/update-cnt.do?id=123&type=free';

나. location.href='/board/update-cnt.do?id=${freeBoard.id}&type=free'"

 

'가' 항은 id와 type값이 둘 다 고정이기 때문에 둘 다 url 주소에 포함되어 있고,

'나' 항은 id는 변수값, type은 고정값이기 때문에 id값만 url 주소에 포함되어 있다.

 

 

 - (참고) ${freeBoardList}는 boardController에서 설정해 둔 표현임

    @RequestMapping("/free-list.do")
    public String freeListView(Model model, @RequestParam Map<String, String> searchMap) {
        boardService = applicationContext.getBean("freeBoardServiceImpl", BoardService.class);

        model.addAttribute("freeBoardList", boardService.getBoardList(searchMap);