71일차 (2) - 조회수 증가 방지

Yohan·2024년 6월 3일
0

코딩기록

목록 보기
109/156
post-custom-banner

조회수 증가 방지 (DB에서 처리)

  • 비회원이거나 본인 글이면 조회수 증가를 방지하는 기능을 넣고자 한다. 이를 처리하기 위해서 서버에서 쿠키를 이용해서 구현할 수 있지만 정석으로는 DB에서 다뤄야하기 때문에 DB를 이용해서 처리한다.

DB

  • Member, board 테이블은 M : N의 다대다 형식을 띄고 있다. 이를 해결하기 위해서는 다대일로 풀어줄 수 있는 중간 테이블이 필요하다. 이를 위해서 view_log 테이블을 생성하고 account, board_no를 외래키로 지정
-- 조회수 기록 관리 테이블
-- M : N 을 해결하기위해 중간 테이블 생성

CREATE TABLE view_log (
	id INT PRIMARY KEY auto_increment,
    account VARCHAR(50),
    board_no INT,
    view_time DATETIME
);

ALTER TABLE view_log
ADD CONSTRAINT fk_member_viewlog
FOREIGN KEY (account)
REFERENCES tbl_member (account);

ALTER TABLE view_log
ADD CONSTRAINT fk_board_viewlog
FOREIGN KEY (board_no)
REFERENCES tbl_board (board_no);

ViewLog

  • DB와 1대1 매칭되는 객체
public class ViewLog {

    private long id;
    private String account;
    private long boardNo;
    private LocalDateTime viewTime;
}

ViewLogMapper

  • 조회수 기록 시간 수정은 1시간이 지났으면 조회수가 또 오르게 하기 위해 만듦

ViewLogMapper.xml

<insert id="insertViewLog">
        INSERT INTO view_log
        (account, board_no, view_time)
        VALUES
        (#{account}, #{boardNo}, #{viewTime})
    </insert>

    <update id="updateViewLog">
        UPDATE view_log
        SET view_time = #{viewTime}
        WHERE account = #{account}
        AND board_no = #{boardNo}
    </update>

    <select id="findOne" resultType="viewLog">
        SELECT *
        FROM view_log
        WHERE account = #{account}
        AND board_no = #{bno}
    </select>

BoardService

        // 비회원이거나 본인 글이면 조회수 증가 방지

        // 로그인 계정명
        String currentUserAccount = getLoggedInUserAccount(session);

        if (!isLoggedIn(session) || isMine(b.getAccount(), currentUserAccount)) {
            return new BoardDetailResponseDto(b); // 게시물만 반환 (조회수 X)
        }

        // 조회수가 올라가는 조건처리 (쿠키버전)
//        if (shouldIncreaseViewCount(bno, request, response)) boardMapper.upViewCount(bno);
//        return new BoardDetailResponseDto(b);


        // 조회수가 올라가는 조건처리 (데이터베이스 버전)

        // 1. 지금 조회하는 글이 기록에 있는지 확인
        int boardNo = b.getBoardNo(); // 게시물 번호
        ViewLog viewLog = viewLogMapper.findOne(currentUserAccount, boardNo);

        boolean shouldIncrease = false; // 조회수 올려도 되는지??
        // 조회 로그 기록 (누가, 어떤 게시글을, 언제 보았는지 기록함)
        ViewLog viewLogEntity = ViewLog.builder()
                .account(currentUserAccount)
                .boardNo(boardNo)
                .viewTime(LocalDateTime.now())
                .build();

        if (viewLog == null) {
            // 2. 이 게시물이 이 회원에 의해 처음 조회됨
            viewLogMapper.insertViewLog(viewLogEntity);
            shouldIncrease = true;
        } else {
            // 3. 조회기록이 있는 경우 - 1시간 이내 인지
            // 혹시 1시간이 지난 게시물인지 확인
            LocalDateTime oneHourAgo = LocalDateTime.now().minusHours(1);
            if (viewLog.getViewTime().isBefore(oneHourAgo)) {
                // 4. db에서 view_time 수정
                viewLogMapper.updateViewLog(viewLogEntity);
                shouldIncrease = true;
            }
        }

        // 처음 조회되거나 조회한지 1시간이 지난 게시물일 경우 조회수 상승하고 게시물 반환
        if (shouldIncrease) {
            boardMapper.upViewCount(boardNo);
        }
        return new BoardDetailResponseDto(b);

    }
profile
백엔드 개발자
post-custom-banner

0개의 댓글