✏️ 구현 전 Entity 상태
📍 연관관계 다이어그램
✏️ 좋아요 기능 설계
- 좋아요 기능을 추가하기 위해서 SiteUser 의 참조를 하나 더 추가해야 한다.
- 글쓴이와 답변자는 1:N , N:1 의 관계지만,
좋아요는 N:N 의 관계이다.
- 하나의 질문에 여러 SiteUser 가 좋아요를 누를 수 있음
- 한명의 SiteUser 가 여러 질문에 좋아요를 누를 수 있음
✏️ Entity 속성 추가
- Qustion, Answer 에 @ManyToMany 어노테이션을 붙여준다.
- 실무에서는 @ManyToMany 를 사용하지 않기 때문에 참고만하자
@ManyToMany
Set<SiteUser> voter;
✏️ Web 계층 - 좋아요 버튼 추가
- 버튼과 좋아요 숫자도 함께 보이도록 구현
- javascript
- 버튼을 누르면 안내 메시지가 나타나게 구현
- 사실상 삭제버튼에 사용했던 로직과 동일하다.
<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>
const recommend_elements = document.getElementsByClassName("recommend");
Array.from(recommend_elements).forEach(function (element) {
element.addEventListener("click", function () {
if (confirm("정말로 추천하시겠습니까?")) {
location.href = this.dataset.uri;
}
});
});
✏️ Service 계층 - 좋아요 추가 기능
- Entity 의 voter 필드에 user 를 추가
@Service
@RequiredArgsConstructor
public class QuestionService {
private final QuestionRepository questionRepository;
public void vote(Question question, SiteUser siteUser) {
question.getVoter().add(siteUser);
questionRepository.save(question);
}
✏️ Controller 계층 - 좋아요 추가 기능
@Controller
@RequestMapping("/question")
@RequiredArgsConstructor
public class QuestionController {
private final QuestionService questionService;
private final UserService userService;
@GetMapping("vote/{id}")
@PreAuthorize("isAuthenticated()")
public String questionVote(
@PathVariable Integer id,
Principal principal
) {
Question question = questionService.getQuestion(id);
SiteUser user = userService.getUser(principal.getName());
questionService.vote(question, user);
return "redirect:/question/detail/" + id;
}