-
Notifications
You must be signed in to change notification settings - Fork 0
#11 Answer 패키지 리팩토링 #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,53 +1,58 @@ | ||
| package com.example.interviewPrep.quiz.answer.controller; | ||
|
|
||
| import com.example.interviewPrep.quiz.answer.dto.AnswerDTO; | ||
| import com.example.interviewPrep.quiz.answer.dto.request.AnswerRequest; | ||
| import com.example.interviewPrep.quiz.answer.dto.response.AnswerResponse; | ||
| import com.example.interviewPrep.quiz.answer.dto.response.SolutionResponse; | ||
| import com.example.interviewPrep.quiz.answer.service.AnswerService; | ||
| import com.example.interviewPrep.quiz.response.ResultResponse; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.data.domain.Page; | ||
| import org.springframework.data.domain.Pageable; | ||
| import org.springframework.data.web.PageableDefault; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| import javax.validation.Valid; | ||
|
|
||
|
|
||
| @RestController | ||
| @RequestMapping("/answer") | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/api/v1/answers") | ||
| @CrossOrigin(origins = "*") | ||
| public class AnswerController { | ||
|
|
||
| private final AnswerService answerService; | ||
|
|
||
| public AnswerController(AnswerService answerService){ | ||
| this.answerService = answerService; | ||
| } | ||
|
|
||
| @PostMapping() | ||
| public ResultResponse<?> createAnswer(@RequestBody @Valid AnswerDTO answerDTO){ | ||
| return ResultResponse.success(answerService.createAnswer(answerDTO)); | ||
| public ResponseEntity<Void> createAnswer(@RequestBody AnswerRequest answerRequest){ | ||
| answerService.createAnswer(answerRequest); | ||
| return ResponseEntity.status(HttpStatus.CREATED).build(); | ||
| } | ||
|
|
||
|
|
||
| @GetMapping("/{id}") | ||
| public ResultResponse<?> readAnswer(@PathVariable Long id){ | ||
| return ResultResponse.success(answerService.readAnswer(id)); | ||
| public ResponseEntity<AnswerResponse> readAnswer(@PathVariable Long id){ | ||
| return ResponseEntity.ok(answerService.readAnswer(id)); | ||
| } | ||
|
|
||
|
|
||
| @DeleteMapping("/{id}") | ||
| public ResultResponse<?> deleteAnswer(@PathVariable Long id){ | ||
| return ResultResponse.success(answerService.deleteAnswer(id)); | ||
| public ResponseEntity<Void> deleteAnswer(@PathVariable Long id){ | ||
| answerService.deleteAnswer(id); | ||
| return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); | ||
| } | ||
|
|
||
|
|
||
| @GetMapping("/solution/{id}/{type}") | ||
| public ResultResponse<?> findSolutionAnswer(@PathVariable Long id, @PathVariable String type, | ||
| @PageableDefault(size=10) Pageable pageable){ | ||
| return ResultResponse.success(answerService.getSolution(id, type, pageable)); | ||
| @GetMapping("/solution/{id}/by-type/{type}") | ||
| public ResponseEntity<Page<SolutionResponse>> findSolutionAnswer(@PathVariable Long id, @PathVariable String type, | ||
| @PageableDefault(size=10) Pageable pageable){ | ||
| return ResponseEntity.ok(answerService.getSolution(id, type, pageable)); | ||
| } | ||
|
|
||
|
|
||
| @GetMapping("/solution/check/{id}") | ||
| public ResultResponse<?> checkMySolution(@PathVariable Long id){ | ||
| public ResponseEntity<Void> checkMySolution(@PathVariable Long id){ | ||
| answerService.checkMySolution(id); | ||
| return ResultResponse.success(); | ||
| return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,73 +2,92 @@ | |
|
|
||
| import com.example.interviewPrep.quiz.domain.BaseTimeEntity; | ||
|
|
||
| // import com.example.interviewPrep.quiz.exam.domain.ExamAnswer; | ||
| import com.example.interviewPrep.quiz.member.domain.Member; | ||
| import com.example.interviewPrep.quiz.question.domain.Question; | ||
| import com.example.interviewPrep.quiz.heart.exception.HeartExistException; | ||
| import com.fasterxml.jackson.annotation.*; | ||
| import lombok.AllArgsConstructor; | ||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
| import lombok.NoArgsConstructor; | ||
|
|
||
| import javax.persistence.*; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.Objects; | ||
|
|
||
| import static javax.persistence.FetchType.LAZY; | ||
|
|
||
| @Entity | ||
| @Getter | ||
| @Builder | ||
| @NoArgsConstructor | ||
| @AllArgsConstructor | ||
| @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class) | ||
| public class Answer extends BaseTimeEntity { | ||
|
|
||
| @Id | ||
| @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| @Column(name = "ANSWER_ID") | ||
| private Long id; | ||
|
|
||
| @Lob | ||
| private String content; | ||
|
|
||
| @ManyToOne(fetch = LAZY) | ||
| @JsonBackReference(value="question-answer") | ||
| @JoinColumn(name = "QUESTION_ID") | ||
| Question question; | ||
|
|
||
| @ManyToOne(fetch = LAZY) | ||
| @JsonBackReference(value="member-answer") | ||
| @JoinColumn(name = "MEMBER_ID") | ||
| Member member; | ||
|
|
||
| private int commentCnt; | ||
|
|
||
| private int heartCnt; | ||
|
|
||
| @Version | ||
| private Long version; | ||
|
|
||
| @Builder | ||
| public Answer(Long id, String content, Question question, Member member, int commentCnt, int heartCnt, Long version){ | ||
|
|
||
| Objects.requireNonNull(id, "id가 null입니다."); | ||
| Objects.requireNonNull(question, "question이 null입니다."); | ||
| Objects.requireNonNull(member, "member이 null입니다."); | ||
|
|
||
| this.id = id; | ||
| this.content = content; | ||
| this.question = question; | ||
| this.member = member; | ||
| this.commentCnt = commentCnt; | ||
| this.heartCnt = heartCnt; | ||
| this.version = version; | ||
| } | ||
|
|
||
| public static Answer createAnswerEntity(Member member, Question question, String content){ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 왜있는걸까요 ? |
||
| return Answer.builder() | ||
| .member(member) | ||
| .question(question) | ||
| .content(content) | ||
| .build(); | ||
| } | ||
|
|
||
|
|
||
| public void change(String content){ | ||
| this.content = content; | ||
| } | ||
|
|
||
| public int increase() { | ||
| public synchronized int increase() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. synchronized가 이런식으로 걸리면 성능에 어떤 영향이 있을까요 ? AtomicInteger에 대해서 찾아보시면 좋을 것 같아요 ~ |
||
| return ++this.heartCnt; | ||
| } | ||
|
|
||
| public int decrease() { | ||
| public synchronized int decrease() { | ||
| if (this.heartCnt <= 0) { | ||
| throw new HeartExistException("좋아요 수가 0보다 작아 좋아요 수를 감소시킬수 없습니다."); | ||
| } | ||
| return --this.heartCnt; | ||
| } | ||
|
|
||
| public int commentIncrease() { return ++this.commentCnt; } | ||
| public synchronized int commentIncrease() { | ||
| return ++this.commentCnt; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 동시에 동일한 답변에 코멘트가 달리는 경우, 이 메서드는 스레드세이프하게 동작할 수 있을까요 ?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 스레드 세이프 하게 동작하지 않을 것 같습니다.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 반영 완료 |
||
| } | ||
|
|
||
| public int commentDecrease() {return --this.commentCnt;} | ||
| public synchronized int commentDecrease() { | ||
| return --this.commentCnt; | ||
| } | ||
|
|
||
| // @OneToMany(mappedBy = "answer") | ||
| // List<ExamAnswer> exams = new ArrayList<>(); | ||
| } | ||
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
개인적으로 성공응답은 그냥 다 200으로 내려도 된다고 생각해요. 성공 상태에 따라서 뭐 분기할 일이 없어서 ..