안녕하세요. 오늘은 정말 간단하게 조회수 기능을 구현하도록 하겠습니다.
지적과 조언 감사하겠습니다.
3. 질문게시글 상세 정보 페이지
-게시글 수정, 삭제, 신고, 주소 복사 기능
-조회수 증가(비로그인, 또는 본인 글이 아닐시에만)
우선 Entity에 조회수 변수가 있어야 합니다.
저는
@Comment("조회수")
@Column(nullable = true)
private int qbViews;
이렇게 추가했습니다.
/**
* 게시판 상세보기
*
* @param mbNo
* @param model
*
*/
@GetMapping("/question/{qbNo}")
public String view(@PathVariable Long qbNo, Model model) {
// 게시판 불러오기
QuestionResponseDto questionResponseDto = questionBoardService.findByQbNo(qbNo);
// 댓글 불러오기
List<QuestionCommentDto> commentList = questionCommentService.findAllQuestionCommentByQbNo(qbNo);
//조회수증가
questionBoardService.updateViewIfNotWriter(qbNo, questionResponseDto.getMember().getMemberNo());
model.addAttribute("detail", questionResponseDto);
model.addAttribute("commentList", commentList);
return "board/question/detail";
}
@Transactional
public void updateViewIfNotWriter(Long qbNo, Integer writerMemberNo) {
Integer loggedInMemberNo = CommonUtil.getMember() != null ? CommonUtil.getMember().getMemberNo() : null;
// 비로그인이거나 작성자가 아닐 경우에만 조회수 증가
if (loggedInMemberNo == null || !writerMemberNo.equals(loggedInMemberNo)) {
questionBoardRepository.updateView(qbNo);
}
}
CommonUtil.getMember() 는 저희 프로젝트에서 Spring Security에서 현재 인증된 사용자의 회원 정보를 가져오는 기능을 합니다.
Member객체에 담아서 주는데, 사실 처음에는 Member객체끼리 비교하려고 했는데요, 이럴 경우 비로그인 경우에는 괜찮은데 로그인 경우에는 지연로딩에러가 뜨더라고요.. 고유번호만 가져오는건 뜨지 않아서 이렇게 처리를 했습니다. ( 사실 고유번호만 있어도 되긴하고요 )
public interface QuestionBoardRepository extends JpaRepository<QuestionBoard,Long>, QuestionBoardRepositoryCustom {
@Modifying
@Query("update QuestionBoard q set q.qbViews = q.qbViews + 1 where q.qbNo = :qbNo")
public void updateView(@Param("qbNo") Long qbNo);
}
JPA에서 제공하는 @Query 애노테이션을 사용하여 JPQL이용하여 조회수 쿼리를 적어줍니다.
@Modifying는 주로 UPDATE, DELETE와 같은 DML(Data Manipulation Language) 쿼리를 실행하는 메소드에 사용되는 어노테이션으로 스프링 데이터 JPA가 해당 메소드를 데이터 수정 작업으로 인식하도록 합니다.
이러면 또 끝입니다...!!!!
조회수가 잘 들어옵니다.
간단한 쿼리문 같은 경우에는 Querydsl을 사용하지 않고 JPQL을 사용하는게 더 좋다는 것을 알게되었습니다.