![25. 추천 구현하기 - 점프 투 스프링부트(게시판 만들기)](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fu7bLg%2FbtrVzGeVSEr%2FE2pZqXbiPrr0vrKVP9iGgK%2Fimg.png)
25. 추천 구현하기 - 점프 투 스프링부트(게시판 만들기)Spring2023. 1. 6. 23:11
Table of Contents
728x90
728x90
해당 게시글은 점프 투 스프링부트 교재를 통한 개인 학습 용도이며 기초 세팅은 생략하였습니다.
자바 8, 스프링부트 2.7.7버전 입니다.
엔티티 변경
질문, 답변의 추천은 추천한 사람(SiteUser 객체)을 질문, 답변 엔티티에 추가해야 한다.
Question
(... 생략 ...)
import java.util.Set;
import jakarta.persistence.ManyToMany;
(... 생략 ...)
public class Question {
(... 생략 ...)
@ManyToMany
Set<SiteUser> voter;
}
Answer
(... 생략 ...)
import java.util.Set;
import jakarta.persistence.ManyToMany;
(... 생략 ...)
public class Answer {
(... 생략 ...)
@ManyToMany
Set<SiteUser> voter;
}
중복 방지를 위해 Set 컬렉션을, 한 사람이 여러 추천을 할 수 있게 하기 위해 @ManyToMany 어노테이션을 사용했다.
질문 추천
질문 추천 버튼
question_detail.html
(... 생략 ...)
<!-- 질문 -->
<h2 class="border-bottom py-2" th:text="${question.subject}"></h2>
<div class="card my-3">
<div class="card-body">
(... 생략 ...)
<div class="my-3">
<a href="javascript:void(0);" class="recommend btn btn-sm btn-outline-secondary"
th:data-uri="@{|/question/vote/${question.id}|}">
추천
<span class="badge rounded-pill bg-success" th:text="${#lists.size(question.voter)}"></span>
</a>
<a th:href="@{|/question/modify/${question.id}|}" class="btn btn-sm btn-outline-secondary"
sec:authorize="isAuthenticated()"
th:if="${question.author != null and #authentication.getPrincipal().getUsername() == question.author.username}"
th:text="수정"></a>
<a href="javascript:void(0);" th:data-uri="@{|/question/delete/${question.id}|}"
class="delete btn btn-sm btn-outline-secondary" sec:authorize="isAuthenticated()"
th:if="${question.author != null and #authentication.getPrincipal().getUsername() == question.author.username}"
th:text="삭제"></a>
</div>
</div>
</div>
(... 생략 ...)
질문의 수정 버튼 좌측에 추가하고 그리고 추천수도 함께 보이도록 했다.
추천 버튼을 클릭하면 href의 속성이 javascript:void(0)으로 되어 있기 때문에 아무런 동작도 하지 않는다.
하지만 class 속성에 "recommend"를 추가하여 자바스크립트를 사용하여 data-uri에 정의된 URL이 호출되도록 할 것이다.
추천 버튼 확인 창
이번에는 삭제 때와는 달리 confirm을 뺏기 때문에 "추천하시겠습니까?"와 같은 확인 창이 나타나지 않을 것이다.
question_detail.html
(... 생략 ...)
<script layout:fragment="script" type='text/javascript'>
const delete_elements = document.getElementsByClassName("delete");
Array.from(delete_elements).forEach(function(element) {
element.addEventListener('click', function() {
if(confirm("정말로 삭제하시겠습니까?")) {
location.href = this.dataset.uri;
};
});
});
const recommend_elements = document.getElementsByClassName("recommend");
Array.from(recommend_elements).forEach(function(element) {
element.addEventListener('click', function() {
location.href = this.dataset.uri;
});
});
</script>
</html>
QuestionController, QuestionService
QuestionController.java
(... 생략 ...)
public class QuestionController {
(... 생략 ...)
@PreAuthorize("isAuthenticated()")
@GetMapping("/vote/{id}")
public String questionVote(Principal principal, @PathVariable("id") Integer id) {
Question question = this.questionService.getQuestion(id);
SiteUser siteUser = this.userService.getUser(principal.getName());
this.questionService.vote(question, siteUser);
return String.format("redirect:/question/detail/%s", id);
}
}
QuestionSerivce.java
(... 생략 ...)
public class QuestionService {
(... 생략 ...)
public void vote(Question question, SiteUser siteUser) {
question.getVoter().add(siteUser);
this.questionRepository.save(question);
}
}
답변 추천
답변 추천도 질문과 똑같이 버튼을 추가하고, 서비스단에 메서드를 추가하면 된다.
올바르게 진행했다면 아래와 같이 될 것이다.
728x90
300x250
@mag1c :: 꾸준히 재밌게
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!