08_Spring_240424(수)_70일차(0) - ★BoardProject★ - 12. 게시판 - 게시글 좋아요

soowagger·2024년 4월 24일

8_Spring

목록 보기
27/38

12. 게시글 좋아요


✅ 좋아요 여부 확인

1번 게시판 - 가장 최근 게시글 DB 추가

/* 좋아요 테이블(BOARD_LIKE) 샘플 데이터 추가 */
INSERT INTO "BOARD_LIKE"
VALUES(1, 1997); -- 1번 회원이 1997번 글에 좋아요를 클릭함

Board 컨트롤러 - boardDetail() 메서드 일부 구문 추가

  • Spring 스펙업으로 클래스에 @SessionAttributes("{loginMember}") 생략 가능

board-mapper.xml 서브쿼리 추가

Board DTO에 필드 추가

// 좋아요 여부 확인
private int likeCheck;

boardDetail.html 좋아요 부분 th 및 삼항연산자 사용

✅ 좋아요 체크/해제/카운트

boardDetail.html 하단에 구문 추가

<script th:inline="javascript">
    
    // - loginMember가 null인 경우 null 반환
    const loginMemberNo = /*[[${session.loginMember?.memberNo}]]*/ "로그인 회원 번호";

    // 현재 게시글 번호를 전역 변수로 저장
    const boardNo = /*[[${board.boardNo}]]*/ "게시글 번호";

    // 현재 게시글 좋아요 여부를 전역 변수로 저장
    let likeCheck = /*[[${board.likeCheck}]]*/ "좋아요 여부";

</script>

<script src="/js/board/boardDetail.js"></script>

boardDetail.js

/* 좋아요 버튼(하트) 클릭 시 비동기로 좋아요 INSERT/DELETE */

// Thymeleaf 코드 해석 순서
// 1: th 코드(java) + Spring EL
// 2. html 코드(+ css, js)



// 1) 로그인한 회원 번호 준비
//      --> session에서 얻어오기
//      --->(session은 서버에서 관리하기 때문에 JS에서 바로 얻어올 방법 없음)

// 2) 현재 게시글 번호 준비
// 3) 좋아요 여부 준비

// 1. #boardLike가 클릭되었을 때

document.querySelector("#boardLike").addEventListener("click", e => {

    // 2. 로그인 상태가 아닌 경우 동작 X
    if(loginMemberNo == null) {
        alert("로그인 후 이용해 주세요.");
        return;
    }

    // 3. 준비된 3개의 변수를 객체로 저장(JSON 변환 예정)
    const obj = {
        "memberNo" : loginMemberNo,
        "boardNo" : boardNo,
        "likeCheck" : likeCheck
    };

    // 4. 좋아요 INSERT/DELETE 비동기 요청
    fetch("/board/like", {
        method : "POST",
        headers : {"Content-Type" : "application/json"},
        body : JSON.stringify(obj)
    })
    .then(resp => resp.text()) // 반환 결과 text 형태로 변환
    .then(count => {
        
        if(count == -1) {
            console.log("좋아요 처리 실패");
            return;
        }

        // likeCheck 값 0 <-> 1 변환
        // -> 클릭될 때 마다 INSERT/DELETE 동작을 번갈아 가면서 하게끔
        likeCheck = likeCheck == 0 ? 1 : 0;

        // 6. 하트를 채웠다/비웠다 바꾸기
        e.target.classList.toggle("fa-regular");
        e.target.classList.toggle("fa-solid");



        // 7. 게시글 좋아요 수 수정
        e.target.nextElementSibling.innerText = count;

    });

});

boardController

/** 게시글 좋아요 체크/해제
 * @param map
 * @return count
 */
@ResponseBody
@PostMapping("like")
public int boardLike(@RequestBody Map<String, Integer> map) {
	
	return service.boardLike(map);
}

boardServiceImpl

// * 게시글 좋아요 체크/해제
@Override
public int boardLike(Map<String, Integer> map) {
	
	int result = 0;
	
	// 1. 좋아요가 체크된 상태인 경우(likeCheck == 1)
	// -> BOARD_LIKE 테이블에 DELETE
	if(map.get("likeCheck") == 1) {
		
		result = mapper.deleteBoardLike(map);

	} else {

	// 2. 좋아요가 해제된 상태인 경우(likeCheck == 0)
	// -> BOARD_LIKE 테이블에 INSERT
		result = mapper.insertBoardLike(map);
	}
	
	// 3. 다시 해당 게시글의 좋아요 개수 조회해서 반환
	if(result > 0) {
		
		return mapper.selectLikeCount(map.get("boardNo"));
	
	}
	
	return -1;
}

board-mapper.xml

<!-- 좋아요 해제 -->
<delete id="deleteBoardLike">
	DELETE FROM "BOARD_LIKE"
	WHERE MEMBER_NO = #{memberNo}
	AND BOARD_NO = #{boardNo}
</delete>

<!-- 좋아요 체크 -->
<insert id="insertBoardLike">
	INSERT INTO "BOARD_LIKE" (MEMBER_NO, BOARD_NO)
	VALUES(#{memberNo}, #{boardNo})
</insert>

<!-- 게시글 좋아요 수 조회 -->
<select id="selectLikeCount">
	SELECT COUNT(*) FROM "BOARD_LIKE"
	WHERE BOARD_NO = #{boardNo}
</select>

profile

0개의 댓글