Skip to main content

03K. ์ถ”์ฒœ

About 3 minJavaSpringAWScrashcoursejavajdkjdk8streamspringspringframeworkspringbootawsaws-ec2

03K. ์ถ”์ฒœ ๊ด€๋ จ


3-11. ์ถ”์ฒœ

์ ํ”„ ํˆฌ ์Šคํ”„๋ง๋ถ€ํŠธ - WikiDocs

pahkey/sbb3 - 3-11open in new window

์ด๋ฒˆ์—๋Š” ์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€์— "์ถ”์ฒœ(์ข‹์•„์š”)" ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ด ๋ณด์ž.


์—”ํ‹ฐํ‹ฐ ๋ณ€๊ฒฝ

์งˆ๋ฌธ, ๋‹ต๋ณ€์˜ ์ถ”์ฒœ์€ ์ถ”์ฒœํ•œ ์‚ฌ๋žŒ(SiteUser ๊ฐ์ฒด)์„ ์งˆ๋ฌธ, ๋‹ต๋ณ€ ์—”ํ‹ฐํ‹ฐ์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

Question

์šฐ์„  Question ์—”ํ‹ฐํ‹ฐ์— ์ถ”์ฒœ์ธ(voter) ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด ๋ณด์ž.

ํ•˜๋‚˜์˜ ์งˆ๋ฌธ์— ์—ฌ๋Ÿฌ์‚ฌ๋žŒ์ด ์ถ”์ฒœํ•  ์ˆ˜ ์žˆ๊ณ  ํ•œ ์‚ฌ๋žŒ์ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์งˆ๋ฌธ์„ ์ถ”์ฒœํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๋“ฏ ์งˆ๋ฌธ๊ณผ ์ถ”์ฒœ์ธ์€ ๋ถ€๋ชจ์™€ ์ž์‹์˜ ๊ด€๊ณ„๊ฐ€ ์•„๋‹ˆ๊ณ  ๋Œ€๋“ฑํ•œ ๊ด€๊ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— @ManyToMany๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ“š์ฐธ๊ณ : https://docs.oracle.com/javaee/7/api/jakarta/persistence/ManyToMany.htmlopen in new window

ํŒŒ์ผ๋ช…:/sbb/src/main/java/com/mysite/sbb/question/Question.java

// (... ์ƒ๋žต ...)
import java.util.Set;
import jakarta.persistence.ManyToMany;
// (... ์ƒ๋žต ...)
public class Question {
    // (... ์ƒ๋žต ...)

    @ManyToMany
    Set<SiteUser> voter;
}

ย 
ย 




ย 
ย 

Set<SiteUser> voter ์ฒ˜๋Ÿผ ์ถ”์ฒœ์ธ(voter)์„ @ManyToMany ๊ด€๊ณ„๋กœ ์ถ”๊ฐ€ํ–ˆ๋‹ค. List๊ฐ€ ์•„๋‹Œ Set์œผ๋กœ ํ•œ ์ด์œ ๋Š” ์ถ”์ฒœ์ธ์€ ์ค‘๋ณต๋˜๋ฉด ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Set์€ ์ค‘๋ณต์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š๋Š” ์ž๋ฃŒํ˜•์ด๋‹ค.

Answer

Answer ์—”ํ‹ฐํ‹ฐ ์—ญ์‹œ ๋งˆ์ฐฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ถ”์ฒœ์ธ(voter) ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜์ž.

ํŒŒ์ผ๋ช…:/sbb/src/main/java/com/mysite/sbb/answer/Answer.java

// (... ์ƒ๋žต ...)
import java.util.Set;
import jakarta.persistence.ManyToMany;
// (... ์ƒ๋žต ...)
public class Answer {
    // (... ์ƒ๋žต ...)

    @ManyToMany
    Set<SiteUser> voter;
}

ย 
ย 




ย 
ย 

ํ…Œ์ด๋ธ” ํ™•์ธ

์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€ ์—”ํ‹ฐํ‹ฐ์— voter ์†์„ฑ์„ ์ถ”๊ฐ€ํ•œํ›„ H2 ์ฝ˜์†”์„ ํ™•์ธํ•ด ๋ณด์ž.
์งˆ๋ฌธ๊ณผ ๋‹ต๋ณ€ ์—”ํ‹ฐํ‹ฐ์— voter ์†์„ฑ์„ ์ถ”๊ฐ€ํ•œํ›„ H2 ์ฝ˜์†”์„ ํ™•์ธํ•ด ๋ณด์ž.

QUESTION_VOTER, ANSWER_VOTER ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ @ManyToMany ๊ด€๊ณ„๋กœ ์†์„ฑ์„ ์ƒ์„ฑํ•˜๋ฉด ์ƒˆ๋กœ์šด ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ํ…Œ์ด๋ธ”์—๋Š” ์„œ๋กœ ์—ฐ๊ด€๋œ ์—”ํ‹ฐํ‹ฐ์˜ ๊ณ ์œ ๋ฒˆํ˜ธ(id) 2๊ฐœ๊ฐ€ ํ”„๋ผ์ด๋จธ๋ฆฌ ํ‚ค๋กœ ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋Œ€๋‹ค(N:N) ๊ด€๊ณ„๊ฐ€ ์„ฑ๋ฆฝํ•˜๋Š” ๊ตฌ์กฐ์ด๋‹ค.


์งˆ๋ฌธ ์ถ”์ฒœ

Question ์—”ํ‹ฐํ‹ฐ์— ์ถ”์ฒœ์ธ ์†์„ฑ์„ ์ถ”๊ฐ€ ํ–ˆ์œผ๋‹ˆ ์ด์ œ ์งˆ๋ฌธ ์ถ”์ฒœ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด ๋ณด์ž.

์งˆ๋ฌธ ์ถ”์ฒœ ๋ฒ„ํŠผ

์งˆ๋ฌธ์„ ์ถ”์ฒœํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ„ํŠผ์˜ ์œ„์น˜๋Š” ์–ด๋””๊ฐ€ ์ข‹์„๊นŒ? ๊ทธ๋ ‡๋‹ค. ์งˆ๋ฌธ ์ƒ์„ธ ํ™”๋ฉด์ด๋‹ค. ์งˆ๋ฌธ ์ƒ์„ธ ํ…œํ”Œ๋ฆฟ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์ž.

ํŒŒ์ผ๋ช…: /sbb/src/main/resources/templates/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์ด ํ˜ธ์ถœ๋˜๋„๋ก ํ•  ๊ฒƒ์ด๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” "์ถ”์ฒœ" ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„๋•Œ ํ™•์ธ์ฐฝ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ํ™•์ธ์„ ๊ตฌํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค.

์ถ”์ฒœ ๋ฒ„ํŠผ ํ™•์ธ ์ฐฝ

์ด์–ด์„œ [<์ถ”์ฒœ>] ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ '์ •๋ง๋กœ ์ถ”์ฒœํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?'๋ผ๋Š” ํ™•์ธ ์ฐฝ์ด ๋‚˜ํƒ€๋‚˜์•ผ ํ•˜๋ฏ€๋กœ ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜์ž.

ํŒŒ์ผ๋ช…:/sbb/src/main/resources/templates/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() {
        if(confirm("์ •๋ง๋กœ ์ถ”์ฒœํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?")) {
            location.href = this.dataset.uri;
        };
    });
});
</script>
</html>










ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 


์ถ”์ฒœ ๋ฒ„ํŠผ์— class="recommend"๊ฐ€ ์ ์šฉ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ถ”์ฒœ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด "์ •๋ง๋กœ ์ถ”์ฒœํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?"๋ผ๋Š” ์งˆ๋ฌธ์ด ๋‚˜ํƒ€๋‚˜๊ณ  ["ํ™•์ธ"]์„ ์„ ํƒํ•˜๋ฉด data-uri ์†์„ฑ์— ์ •์˜ํ•œ URL์ด ํ˜ธ์ถœ๋  ๊ฒƒ์ด๋‹ค.

QuestionService

๊ทธ๋ฆฌ๊ณ  ์ถ”์ฒœ์ธ์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด QuestionSerivce๋ฅผ ์ˆ˜์ •ํ•˜์ž.

ํŒŒ์ผ๋ช…:/sbb/src/main/java/com/mysite/sbb/question/QuestionService.java

// (... ์ƒ๋žต ...)
public class QuestionService {

    // (... ์ƒ๋žต ...)

    public void vote(Question question, SiteUser siteUser) {
        question.getVoter().add(siteUser);
        this.questionRepository.save(question);
    }
}





ย 
ย 
ย 
ย 

Question ์—”ํ‹ฐํ‹ฐ์— ์‚ฌ์šฉ์ž๋ฅผ ์ถ”์ฒœ์ธ์œผ๋กœ ์ €์žฅํ•˜๋Š” vote ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

QuestionController

์ด์ œ ์ถ”์ฒœ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„๋•Œ ํ˜ธ์ถœ๋˜๋Š” URL์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด QuestionController๋ฅผ ์ˆ˜์ •ํ•˜์ž.

ํŒŒ์ผ๋ช…:/sbb/src/main/java/com/mysite/sbb/question/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);
    }
}

์œ„์™€ ๊ฐ™์ด questionVote ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค. ์ถ”์ฒœ์€ ๋กœ๊ทธ์ธํ•œ ์‚ฌ๋žŒ๋งŒ ๊ฐ€๋Šฅํ•ด์•ผ ํ•˜๋ฏ€๋กœ @PreAuthorize("isAuthenticated()") ์• ๋„ˆํ…Œ์ด์…˜์ด ์ ์šฉ๋˜์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์œ„์—์„œ ์ž‘์„ฑํ•œ QuestionService์˜ vote ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ถ”์ฒœ์ธ์„ ์ €์žฅํ–ˆ๋‹ค. ์˜ค๋ฅ˜๊ฐ€ ์—†๋‹ค๋ฉด ์งˆ๋ฌธ ์ƒ์„ธํ™”๋ฉด์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํ•œ๋‹ค.

์งˆ๋ฌธ ์ถ”์ฒœ ํ™•์ธ

์งˆ๋ฌธ ์ƒ์„ธ ํ™”๋ฉด์˜ ๋ณธ๋ฌธ ์ƒ๋‹จ์„ ๋ณด๋ฉด <FontIcon icon="iconfont icon-select"/> ๋ฒ„ํŠผ์ด ์ƒ๊ฒผ์„ ๊ฒƒ์ด๋‹ค. ๋ฒ„ํŠผ์ด ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์ž.
์งˆ๋ฌธ ์ƒ์„ธ ํ™”๋ฉด์˜ ๋ณธ๋ฌธ ์ƒ๋‹จ์„ ๋ณด๋ฉด [์ถ”์ฒœ] ๋ฒ„ํŠผ์ด ์ƒ๊ฒผ์„ ๊ฒƒ์ด๋‹ค. ๋ฒ„ํŠผ์ด ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜์ž.

๋‹ต๋ณ€ ์ถ”์ฒœ

๋‹ต๋ณ€ ์ถ”์ฒœ ๊ธฐ๋Šฅ์€ ์งˆ๋ฌธ ์ถ”์ฒœ ๊ธฐ๋Šฅ๊ณผ ๋™์ผํ•˜๋ฏ€๋กœ ๋น ๋ฅด๊ฒŒ ์ž‘์„ฑํ•ด ๋ณด์ž.

๋‹ต๋ณ€ ์ถ”์ฒœ ๋ฒ„ํŠผ

๋‹ต๋ณ€์˜ ์ถ”์ฒœ์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๊ณ , ๋‹ต๋ณ€์„ ์ถ”์ฒœํ•  ์ˆ˜์žˆ๋Š” ๋ฒ„ํŠผ์„ ์งˆ๋ฌธ ์ƒ์„ธ ํ…œํ”Œ๋ฆฟ์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€ํ•˜์ž.

ํŒŒ์ผ๋ช…:/sbb/src/main/resources/templates/question_detail.html

<!-- (... ์ƒ๋žต ...) -->
<!-- ๋‹ต๋ณ€ ๋ฐ˜๋ณต ์‹œ์ž‘ -->
<div class="card my-3" th:each="answer : ${question.answerList}">
    <div class="card-body">
        <!-- (... ์ƒ๋žต ...) -->
        <div class="my-3">
            <a href="javascript:void(0);" class="recommend btn btn-sm btn-outline-secondary"
                th:data-uri="@{|/answer/vote/${answer.id}|}">
                ์ถ”์ฒœ
                <span class="badge rounded-pill bg-success" th:text="${#lists.size(answer.voter)}"></span>
            </a>
            <a th:href="@{|/answer/modify/${answer.id}|}" class="btn btn-sm btn-outline-secondary"
                sec:authorize="isAuthenticated()"
                th:if="${answer.author != null and #authentication.getPrincipal().getUsername() == answer.author.username}"
                th:text="์ˆ˜์ •"></a>
            <a href="javascript:void(0);" th:data-uri="@{|/answer/delete/${answer.id}|}"
                class="delete btn btn-sm btn-outline-secondary" sec:authorize="isAuthenticated()"
                th:if="${answer.author != null and #authentication.getPrincipal().getUsername() == answer.author.username}"
                th:text="์‚ญ์ œ"></a>
        </div>
    </div>
</div>
<!-- ๋‹ต๋ณ€ ๋ฐ˜๋ณต ๋  -->
<!-- (... ์ƒ๋žต ...) -->






ย 
ย 
ย 
ย 
ย 













์งˆ๋ฌธ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹ต๋ณ€ ์˜์—ญ์˜ ์ƒ๋‹จ์— ๋‹ต๋ณ€์„ ์ถ”์ฒœํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ„ํŠผ์„ ์ƒ์„ฑํ–ˆ๋‹ค. ์ด ์—ญ์‹œ ์ถ”์ฒœ ๋ฒ„ํŠผ์— class="recommend"๊ฐ€ ์ ์šฉ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ถ”์ฒœ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด "์ •๋ง๋กœ ์ถ”์ฒœํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?"๋ผ๋Š” ์งˆ๋ฌธ์ด ๋‚˜ํƒ€๋‚˜๊ณ  ["ํ™•์ธ"]์„ ์„ ํƒํ•˜๋ฉด data-uri ์†์„ฑ์— ์ •์˜ํ•œ URL์ด ํ˜ธ์ถœ๋  ๊ฒƒ์ด๋‹ค.

AnswerService

๊ทธ๋ฆฌ๊ณ  ๋‹ต๋ณ€์— ์ถ”์ฒœ์ธ์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด AnswerService๋ฅผ ์ˆ˜์ •ํ•˜์ž.

ํŒŒ์ผ๋ช…:/sbb/src/main/java/com/mysite/sbb/answer/AnswerService.java

// (... ์ƒ๋žต ...)
public class AnswerService {

    // (... ์ƒ๋žต ...)

    public void vote(Answer answer, SiteUser siteUser) {
        answer.getVoter().add(siteUser);
        this.answerRepository.save(answer);
    }
}





ย 
ย 
ย 
ย 

Answer ์—”ํ‹ฐํ‹ฐ์— ์‚ฌ์šฉ์ž๋ฅผ ์ถ”์ฒœ์ธ์œผ๋กœ ์ €์žฅํ•˜๋Š” vote ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

AnswerController

์ด์ œ ๋‹ต๋ณ€ ์ถ”์ฒœ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„๋•Œ ํ˜ธ์ถœ๋˜๋Š” URL์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด AnswerController๋ฅผ ์ˆ˜์ •ํ•˜์ž.

ํŒŒ์ผ๋ช…:/sbb/src/main/java/com/mysite/sbb/answer/AnswerController.java

// (... ์ƒ๋žต ...)
public class AnswerController {

    // (... ์ƒ๋žต ...)

    @PreAuthorize("isAuthenticated()")
    @GetMapping("/vote/{id}")
    public String answerVote(Principal principal, @PathVariable("id") Integer id) {
        Answer answer = this.answerService.getAnswer(id);
        SiteUser siteUser = this.userService.getUser(principal.getName());
        this.answerService.vote(answer, siteUser);
        return String.format("redirect:/question/detail/%s", answer.getQuestion().getId());
    }
}





ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

์œ„์™€ ๊ฐ™์ด answerVote ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค. ์ถ”์ฒœ์€ ๋กœ๊ทธ์ธํ•œ ์‚ฌ๋žŒ๋งŒ ๊ฐ€๋Šฅํ•ด์•ผ ํ•˜๋ฏ€๋กœ @PreAuthorize("isAuthenticated()") ์• ๋„ˆํ…Œ์ด์…˜์ด ์ ์šฉ๋˜์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์œ„์—์„œ ์ž‘์„ฑํ•œ AnswerService์˜ vote ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ถ”์ฒœ์ธ์„ ์ €์žฅํ•œ๋‹ค. ์˜ค๋ฅ˜๊ฐ€ ์—†๋‹ค๋ฉด ์งˆ๋ฌธ ์ƒ์„ธํ™”๋ฉด์œผ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ํ•œ๋‹ค.

๋‹ต๋ณ€ ์ถ”์ฒœ ํ™•์ธ

์ด์™€ ๊ฐ™์ด ์ˆ˜์ • ํ›„ ๋‹ต๋ณ€ ์ถ”์ฒœ ๊ธฐ๋Šฅ๋„ ํ™•์ธํ•ด ๋ณด์ž.
์ด์™€ ๊ฐ™์ด ์ˆ˜์ • ํ›„ ๋‹ต๋ณ€ ์ถ”์ฒœ ๊ธฐ๋Šฅ๋„ ํ™•์ธํ•ด ๋ณด์ž.

์ด์ฐฌํฌ (MarkiiimarK)
Never Stop Learning.