조회수 카운트

MJ·2024년 3월 8일
post-thumbnail
  • 특정 게시물을 조회할 때마다 조회수를 증가시킵니다.
  • ※ 세션 당 1회만 조회수를 증가시킬 것 (중복 방지)




    < BoardRepository 추가 코드 >

    @Modifying
    @Query("update Board p set p.count = p.count +1 where p.id = :id")
    int updateView(Long id);
    
    // update Board p : 수정할 엔터티는 Board 이고 p 라고 칭합니다.
    // set p.count = p.count + 1 : 엔터티 p의 count 속성을 1 증가 시킵니다.
    // where p.id = :id : 해당 게시글의 id와 일치하는 레코드에만 조회수를 증가 시킵니다.

    < BoardService 추가 코드 >

    private void BoardDetail(Long id) { // 게시글 상세보기 - 조회수 기능 추가

        Optional<Board> board = boardRepository.findById(id); // ID를 사용하여 게시글을 조회합니다. 게시글이 존재하면 Optional로 감싸진 게시글 객체를 반환합니다.
        if (board.isPresent()) { //isPresent() 메서드는 Optional 객체 안에 값이 존재하는지 여부를 반환합니다.
            Board boardEntity = board.get(); // Optional 객체 안에 존재하는 게시글 객체를 가져옵니다.
            boardEntity.incrementViewCount(); // 게시글의 조회수를 증가시킵니다. (incrementViewCount()는 엔터티에 정의된 메서드이며 조회수를 1 증가시키는 역할을 합니다.)
            boardRepository.save(boardEntity); // 조회수 정보를 저장합니다.
    
        } else {
            throw new EntityNotFoundException("게시글을 찾을 수 없습니다." + id);
        }
    
    
    }



    private boolean hasViewedPost(Long id) { //세션에서 조회한 게시글인지 확인하는 메서드 addViewedPostToSession에서 사용

        Set<Long> viewedPosts = Optional.ofNullable((Set<Long>) session.getAttribute("viewedPosts")).orElse(Collections.emptySet());// 속성을 가져오는 부분은 추후에 해당 속성을 업데이트 하거나 사용할 때 유용하게 활용될 수 있도록 준비하는 단계입니다.
        //세션에서 viewedPosts 속성을 가져옵니다. Optional.ofNullable()은 가져온 속성이 null인지 확인하고, 그렇지 않은 경우에만 Optional 객체를 생성합니다. 가져온 속성을  set<Long> 타입으로 형변환 합니다.
        //.orElase(Collections.emptySet()) 가져온 속성이 null인 경우에는 빈 Set을 반환합니다. null 체크를 통해서 NullPointException을 방지합니다.
    
        return viewedPosts.contains(id); // 형변환된 조회한 게시글 집합에 지정된 ID가 포함되어 있는지 확인하고, 그 결과를 반환합니다.
    
    }



    private void addViewedPostToSession(Long id) { //세션에 조회한 게시글을 추가하는 메서드

     if(viewedPosts == null) { // viewed 속성이 null 이라면
         viewedPosts = new HashSet<>(); // 새로운 HashSet을 생성하여 조회한 게시글의 ID를 관리할 준비를 합니다.
    
     }
     viewedPosts.add(id); // 조회한 게시글의 ID를 viewedPosts 속성에 추가합니다.
     session.setAttribute("viewedPosts", viewedPosts); // 세션에 있는 viewedPosts 속성을 업데이트 합니다. 
    }
    



    public BoardDto getCompleteBoardDetail(Long id) { // 게시글 상세페이지 controller 호출

         if(!hasViewedPost(id)){ //해당 게시글이 이미 조회되었는지 확인합니다.
             BoardDetail(id); //해당 게시글이 조회되지 않았으면 게시글의 조회수를 증가시킵니다.
             addViewedPostToSession(id); //조회된 게시물 ID를 세션에 기록하여 중복 조회를 방지합니다.
         }
    
        return getPostDetail(id);
    }



    < Board 추가 코드 >

    
     @Column(columnDefinition = "integer default 0", nullable = false)
      private Long viewCount=0L; //조회수를 저장하는 컬럼입니다. 기본값을 0으로 설정합니다.
    
     public void incrementViewCount(){ //조회수를 증가시키는 메서드입니다.
          this.viewCount++; // 조회수를 1 증가시킵니다.
    
      }



    사용자가 동일한 세션에서 여러 번 페이지를 조회 해도 조회수가 증가하지 않습니다. (중복제거)

    세션 데이터가 서버 메모리에 저장되어 중복 조회를 필터링 할 수 있습니다.
    하지만 동시에 많은 사용자가 접속하는 경우 서버 부하가 증가 할 수 있기 때문에
    외부 스토리지에 저장하는 것을 권장한다고 합니다.
    현재는 로컬에서 공부하는 용도이기 때문에 추후에 데이터베이스에 저장하는 것을 구현해볼 생각입니다.

    외부 스토리지 목록

    분산 파일 시스템

  • Hadoop HDFS (Hadoop Distributed File System)
  • GlusterFS
  • Ceph
  • 클라우드 스토리지 서비스

  • Amazon S3 (Simple Storage Service)
  • Google Cloud Storage
  • Microsoft Azure Storage
  • 캐시 서버

  • Redis
  • Memcached
  • 데이터베이스 서비스

  • MySQL
  • PostgreSQL
  • MongoDB

  • profile
    안녕하세요. WeekDays 개발 진행 상황을 기록하는 공간입니다.

    0개의 댓글