[TIL] Day42 - 게시글 좋아요

JIONY·2022년 11월 10일
0

TIL - Web BE - Spring Boot

목록 보기
18/20
post-thumbnail

개인의 좋아요 기록을 남기는 테이블만 있으면 게시글의 좋아요 개수는 count만 하면 되는 거라니..! 재밌었땅 ㅎㅎ 수업시간에 구현한 방식은 게시글 상세에 들어가야만 나의 좋아요 여부 확인이 가능한데, 게시글 목록에서 내가 좋아요한 글을 확인하는 것도 해봐야겠음


좋아요(게시글)

  • 회원이 게시글에 표시하는 것
  • 관계(Relation)에 해당하는 기능
  • 하나의 회원이 하나의 게시글에 단 한 번만 가능
    • 누가 어디에 좋아요를 눌렀는지 저장해야 함
    • 중복제거 철저히 해야 함
      -> 세션만 이용하지 않고 DB를 이용해 별도의 테이블을 만들어서 정보를 저장

테이블 설계

  • member_id, board_no를 외래키로 사용
    • 회원&게시글: 복합키(composite key)로 설정
  • like_time: 좋아요를 누른 시간 저장하는 컬럼 추가(없어도 됨)
    • 내가 좋아요 누른 글 리스트에서 언제 눌렀는지 보여주는 데 사용 예정
create table member_board_like(
member_id references member(member_id) on delete cascade not null,
board_no references board(board_no) on delete cascade not null,
like_time date default sysdate not null,
primary key(member_id, board_no)
);

Dao, DaoImpl

  • 기능: 등록/삭제/검사 총 세 개 필요
    • 좋아요는 두 가지 상태를 왔다갔다 하는 토글 기능이므로 같은 주소로 처리할 수 있음
    • 좋아요 검사: 복합키(회원&게시글) 사용한 단일 조회, 결과 개수가 1인지 여부 return(1이면 좋아요)

flow

  • 게시글 상세에서 좋아요/취소 시 게시글 번호 전달
  • redirect: detail(게시글 번호 전달)

Controller

좋아요 기록 조회

  • 좋아요 기록이 있는지 조회해서 첨부(회원만)
String memberId = (String)session.getAttribute(SessionConstant.ID);
if(memberId != null) {
	MemberBoardLikeDto likeDto = new MemberBoardLikeDto();
	likeDto.setMemberId(memberId);
	likeDto.setBoardNo(boardNo);
	model.addAttribute("isLike", boardLikeDao.check(likeDto));
}

좋아요 or 취소

@GetMapping("/like")
public String boardLike(@RequestParam int boardNo,
			HttpSession session,
			RedirectAttributes attr) {		
	String memberId = (String)session.getAttribute(SessionConstant.ID);
	MemberBoardLikeDto dto = new MemberBoardLikeDto();
	dto.setMemberId(memberId);
	dto.setBoardNo(boardNo);
	if(boardLikeDao.check(dto)) {//좋아요 상태면
		boardLikeDao.delete(dto); //좋아요 지우기
	}else {
		boardLikeDao.insert(dto); //좋아요 등록
	}
	attr.addAttribute("boardNo", boardNo);
	return "redirect:/board/detail";
}

detail.jsp

  • 글-댓글 사이에 좋아요 버튼(상태 반영) 추가
    • 이미지 vs. 텍스트 천~만배 용량 차이
  • 비회원은 좋아요 누를 수 없도록 처리
<!-- 좋아요 -->
	<c:if test="${isLike == null}">
		<div>
			<a href="/member/login"></a>
			<br>
			좋아요를 누르려면 로그인하세요
		</div>
	</c:if>
	
	<c:if test="${isLike == true}">
		<div>
			<a href="like?boardNo=${dto.boardNo}"></a>
			<br>
			좋아요 취소
		</div>
	</c:if>
	
	<c:if test="${isLike == false}">
		<div>
			<a href="like?boardNo=${dto.boardNo}"></a>
			<br>
			좋아요
			</div>
	</c:if>


좋아요 개수(게시글)

  • 비회원도 조회 가능

Dao, DaoImpl

  • 게시글 번호만 있으면 됨
  • 아래 조회 쿼리 활용
select count(*)
from member_board_like
where board_no = ?;

Controller

  • 게시글 상세 > 현재 글의 좋아요 개수 첨부
model.addAttribute("likeCount", boardLikeDao.count(boardNo));

detail.jsp

  • 컨트롤러에서 첨부한 likeCount 출력


좋아요 수 출력(목록)

  • 이미 조인을 한 번 했기 때문에 어려워짐
    • 너무 많은 테이블을 불러와서 합쳐서 조회하면 성능 낭비일 수 있음
    • 불러오는 게 이상적이지만 그렇지 않아도 된다면 아래 방법으로 처리
  • board 테이블에 좋아요 개수 저장하는 컬럼 추가, 좋아요 등록/취소 될 때마다 개수 변경하도록 처리
    • 바꾸고 갱신시키는 거니까 개수가 정확하지 않을 수 있음
    • 좋아요 내역이 필요하면 join 해야 함

Dao

  • 좋아요 내역 테이블에서 특정 게시글에 대한 데이터 개수를 구해서 게시글 테이블의 좋아요 수 컬럼과 동기화
@Override
public void refresh(int boardNo) {
	String sql = "update board "
				+ "set board_like = ("
                  + "select count(*) "
                  + "from member_board_like "
                  + "where board_no = ?) "
				+ "where board_no = ?";
				
	Object[] param = {boardNo, boardNo}; //홀더 개수만큼 파라미터 사용
	jdbcTemplate.update(sql, param);
}

Controller

  • 좋아요/취소 상관 없이 좋아요 내역 등록/삭제 끝나면 refresh()
boardLikeDao.refresh(boardNo); //좋아요 수 갱신

View

  • 게시글 상세, 목록에 좋아요 개수 출력 구문 추가

0개의 댓글