77일차
좋아요 버튼을 누르면 좋아요가 토글되게 db에 저장 삭제 되게 만들었다.
요구사항
1.로그아웃에서 좋아요 누르면 로그인 하라는 알람
2.로그인 상태에서 게시물 보면 좋아요한 게시물은 꽉찬 하트 안한 게시물은 빈하트
참조키 제약사항으로 인해
3.탈퇴시 좋아요 테이블 데이터 삭제하기
4.게시물 삭제시 좋아요 테이블 데이터 삭제
6.게시물 목록 게시물 볼때 좋아요 몇갠지 표시 + 좋아요클릭시 좋아요 수 업데이트
7.게시물 보기에서 좋아요 수 표시
8.css
84. 로그아웃상태
로그아웃 상태에서 좋아요 누르면 로그인 하라는 알람을 띄워보자.
로그인하지않앗으면 authentication이 null이라서 500에러가 발생한다.
84.1 컨트롤러
먼저 컨트롤러에서 조건처리를 해줘야한다.
ResponseEntity.status(상태코드).body(map)바디설정
권한이 없다는 403에러를 주게 해주자. 403에러는 권한때문에 요청을 거부했다는 것이다.
@PostMapping("/like")
@ResponseBody
public ResponseEntity<Map<String, Object>> like(@RequestBody Like like, Authentication authentication) {
if (authentication == null) {
return ResponseEntity
.status(403)
.body(Map.of("message", "로그인 후 좋아요 클릭해주세요"));
} else {
return ResponseEntity.ok().body(service.like(authentication, like));
}
}84.2 실패시 ajax처리
success면 json data를 알아서 파싱해준다.
error라면 jqXHR로 넘어오게 된다 이것을 JSON으로 꺼내서 사용해야한다.
responseText respnaseXML을 가지고 있다.
jqXHR은 responseJSON프로퍼티를 가지고 있다.
jqXHR.responseJSON.message하면 message가 출력되게 된다.
ajax주고받을때 간단히 알람을 보여주는 것을 부트스트랩의 toasts을 사용할 수 있다.
https://getbootstrap.com/docs/5.3/components/toasts/ajax가 오면 body내용을 채워줄것이다.
bootStrap이 jquery를 사용하고 있는게 아니라서 toast객체를 만들어줘야한다.
<div class="toast-container top-0 start-50 translate-middle-x p-3">
<div id="liveToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body"></div>
</div>
</div>$("#likeIcon").click(function() {
const boardId = $("#boardIdText").text().trim();
const data = { boardId };
const toast = new bootstrap.Toast(document.querySelector("#liveToast"));
$.ajax("/like", {
method: "post",
contentType: "application/json",
data: JSON.stringify(data),
success: function(data) {
if (data.like) {
$("#likeIcon").html(`<i class="fa-solid fa-heart"></i>`);
} else {
$("#likeIcon").html(`<i class="fa-regular fa-heart"></i>`);
}
},
error: function(jqXHR) {
$(".toast-body").text(jqXHR.responseJSON.message);
toast.show();
}
//complete:,
});
});85. 게시물 보기에서 좋아요 수 표시
몇개의 좋아요가 있는지 detail페이지 get요청시 담아서 보내줘야한다.
SQL문은 서브쿼리로 각 게시물당 좋아요 수를 뽑아서 각각에 붙여줬다.
JOIN으로는 안되는 듯?
@Select("""
SELECT b.id, b.title, b.body, b.writer, b.inserted, f.fileName,
(SELECT COUNT(*) FROM BoardLike WHERE boardId = b.id) likeCount
FROM Board b
LEFT JOIN FileName f ON b.id = f.boardId
WHERE b.id = #{id}
""")
@ResultMap("boardResultMap")
Board selectById(Integer id);86. 좋아요 수 목록에 표시
목록을 불러오는 것은 BoardView로 따로 테이블을 만들어놨었기 때문에 추가해줘야한다.
쿼리문에 마찬가지로 likeCount를 추가해줘야한다.
SELECT b.*, count(f.id) fileCount,
(SELECT COUNT(*) FROM BoardLike WHERE boardId = b.id) likeCount87. 좋아요 토글시 좋아요 숫자 변하게 하기
json으로 count를 넘겨주고 ajax로 값을 얻은 후 업데이트 해주기
@Override
public Map<String, Object> like(Authentication authentication, Like like) {
Map<String, Object> result = new HashMap<>();
result.put("like", false);
like.setMemberId(authentication.getName());
Integer deleteCnt = likeMapper.delete(like);
if (deleteCnt != 1) {
Integer insertCnt = likeMapper.insert(like);
result.put("like", true);
}
Integer count = likeMapper.countByBoardId(like.getBoardId());
result.put("count", count);
return result;
}$("#likeNumber").text(data.count);88. 좋아요 에따라 표시
처음 글을 보러 올때 꽉찬 하트여야한다.
로그인이 되어잇을때 이름이 있다면 board테이블의 liked를 true로해주기
@Override
public Board getBoard(Integer id, Authentication authentication) {
Board board = mapper.selectById(id);
//현재 로그인하란 사람이 이 게시물에 좋아요 했는지?
if (authentication != null) {
Like like = likeMapper.select(id, authentication.getName());
if (like != null) {
board.setLiked(true);
}
}
return board;
}view에서는 이 값이 true면 꽉찬 하트 아니라면 빈하트이면된다.
<c:if test="${board.liked}">
<i class="fa-solid fa-heart"></i>
</c:if>
<c:if test="${!board.liked}">
<i class="fa-regular fa-heart"></i>
</c:if>89. 회원탈퇴시 좋아요 테이블 데이터 삭제
내풀이 강사님풀이와 같다.
mapper에서 해당 아이디의 like를 삭제해버리기
likeMapper.removeByWriter(member.getId());@Delete("""
DELETE FROM BoardLike
WHERE memberId = #{memberId}
""")
void removeByMemberId(String memberId);90. 게시물 삭제시 좋아요 테이블 데이터 삭제
내풀이 강사님풀이와 같다.
mapper에서 해당 게시물의 like를 삭제해버리기
likeMapper.deleteByBoardId(id);@Delete("""
DELETE FROM BoardLike
WHERE boardId = #{boardId}
""")
void deleteByBoardId(Integer boardId);2023.05.16
서비스는 기능을 담는 것이다.
그저 mapper에서값을 가져오는것만은 기능이 아니다.!!
좋아요처럼 이전글 다음글도 board dto안에 담는게 맞다.
곧 팀프로젝트가 진행될것같다.
막상 하려니 할수잇엇을거 같은것도 하나도 못할거 같은 느낌이든다.
'국비 > Project - 1 게시판' 카테고리의 다른 글
| 2023.05.22 81일차 -1 Project (0) | 2023.05.22 |
|---|---|
| 2023.05.19 80일차 Project (0) | 2023.05.19 |
| 2023.05.15 76일차 Project (0) | 2023.05.16 |
| 2023.05.12 75일차 Project (0) | 2023.05.12 |
| 2023.05.11 74일차 Project (0) | 2023.05.11 |