스프링부트로 게시판 만들기 프로젝트 중 추가 기능인 조회수 기능을 구현해보기로 했다.
여기에 단순히 클릭시 카운트만 올라가는 게 아니라 실제 서비스 되고 있는 게시판처럼 한 계정이 중복으로 조회수를 올릴 수 없게 구현하기로 단서를 걸었다.
@Column(columnDefinition = "integer default 0", nullable = false) // 조회수의 기본 값을 0으로 지정, null 불가 처리
private int view;
}
조회수 컬럼을 추가 후 기본 값을 0으로 지정, null 불가 처리
@Modifying
@Query("update Question q set q.view = q.view + 1 where q.id = :id")
int updateView(@Param("id") Integer id);
QuestionRepository에 해당 게시물의 조회수만 증가시키는 메소드 추가
@Modifying :
@Modifying 어노테이션은 @Query 어노테이션에서 작성된 조회를 제외한 데이터의 변경이 있는
삽입(Insert), 수정(Update), 삭제(Delete) 쿼리 사용시 필요한 어노테이션이다.
출처: https://dev-coco.tistory.com/113 [슬기로운 개발생활:티스토리]
이런 어노테이션이 있는 줄 진작에 알았으면 카테고리 기능 개발할때 그렇게 삽질을 안 했을텐데...
/* Views Counting */
@Transactional
public int updateView(Integer id) {
return this.questionRepository.updateView(id);
}
@Transactional :
@Transactional은 클래스나 메서드에 붙여줄 경우, 해당 범위 내 메서드가 트랜잭션이 되도록 보장해준다.
출처 : https://kafcamus.tistory.com/30
@RequestMapping("/detail/{cate}/{id}")
public String detail(Model model,
@PathVariable("id") Integer id,
@PathVariable("cate") String cate,
AnswerForm answerForm, CommentForm commentForm,
@RequestParam(value="page", defaultValue="0") int page,
HttpServletRequest request,
HttpServletResponse response) {
Question question = this.questionService.getQuestion(id);
/* 조회수 로직 */
Cookie oldCookie = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("postView")) {
oldCookie = cookie;
}
}
}
if (oldCookie != null) {
if (!oldCookie.getValue().contains("["+ id.toString() +"]")) {
this.questionService.updateView(id);
oldCookie.setValue(oldCookie.getValue() + "_[" + id + "]");
oldCookie.setPath("/");
oldCookie.setMaxAge(60 * 60 * 24); // 쿠키 시간
response.addCookie(oldCookie);
}
} else {
this.questionService.updateView(id);
Cookie newCookie = new Cookie("postView", "[" + id + "]");
newCookie.setPath("/");
newCookie.setMaxAge(60 * 60 * 24); // 쿠키 시간
response.addCookie(newCookie);
}
Page<Answer> answerPaging = this.answerService.getAnswerList(id, page); // answerList는 페이징처리하여 별도로 조회하기
model.addAttribute("question", question);
model.addAttribute("answerPaging", answerPaging);
return "/question/question_detail";
}
먼저, 조회수를 올리는데 쿠키를 활용하기 위해 request, response를 파라미터에 추가했다.
먼저, 게시판 목록. 테스트를 한 탓에 몇 개의 게시물 번호가 postView에 추가 되었다. 저 번호의 게시물들을 클릭해도 조회수가 올라가지 않을 것이다.
304번 게시물을 클릭하자 postView에 [304]가 추가 되었다. 신기신기.
304번 게시물 조회수가 1 올라간 것이 보인다.
이후 뒤로 가기를 한 다음에 다시 304번 게시물을 클릭해도 조회수는 올라가지 않는다.
https://dev-coco.tistory.com/113
https://mighty96.github.io/til/view/
안녕하세요 작성하신 조회수 쿠키 구현 도움이 되었습니다