https://wikidocs.net/book/7601
3-15 추가 기능의 조회수를 구현해보았다.
다른 블로그들은 보통 Entity, Repository, Service, Controller를 모두 수정하여 구현했는데, 그 방법을 따라해보면 메인 화면은 잘 뜨는데 특정 게시글 클릭 시 오류가 계속 났었다. Controller에서 Question을 get한 이후에 update가 되게끔 순서를 잘못 기재해서 발생한 오류인가 싶어서 수정을 했는데도 오류가 났다. 여러 블로그를 참고해서 똑같이 구현했는데 왜 나만 오류가 난 건지 모르겠지만!? 아직 내 실력으로는 원인이 뭔지 알 수 없어서 조회수를 구현할 다른 방법을 찾았다.
* 방법1 *
Question 엔티티 필드 추가
@Column(columnDefinition = "integer default 0", nullable = false)
private int view;
Service 코드 수정
public Question getQuestion(Integer id) {
Optional<Question> oq = questionRepository.findById(id);
if(oq.isPresent()) {
return oq.get();
} else {
throw new DataNotFoundException("question not found");
}
}
기존 코드
public Question getQuestion(Integer id) {
Optional<Question> oq = questionRepository.findById(id);
if(oq.isPresent()) {
Question question = oq.get();
question.setView(question.getView() + 1);
questionRepository.save(question);
return question;
} else {
throw new DataNotFoundException("question not found");
}
}
수정 코드
html 파일 수정
...
<th>조회수</th>
...
<td th:text="${question.view}"></td>
question_list.html 추가
<div th:text="|조회수 : ${question.view}|" class="d-flex justify-content-end fw-bold"></div>
question_detail.html 추가
* 방법 2 *
Question 엔티티 필드 추가
@Column(columnDefinition = "integer default 0", nullable = false)
private int view;
Service > updateView 메서드 추가
@Transactional
public Question updateView(Integer id) {
Question question = getQuestion(id);
question.setView(question.getView() + 1);
return question;
}
question의 view를 +1 하고 다시 return한다.
Controller 코드 수정
@GetMapping(value = "/detail/{id}")
public String detail(Model model, @PathVariable("id") Integer id, AnswerForm answerForm) {
Question q = questionService.getQuestion(id);
model.addAttribute("question", q);
return "question_detail";
}
기존 코드
@GetMapping(value = "/detail/{id}")
public String detail(Model model, @PathVariable("id") Integer id, AnswerForm answerForm) {
Question question = questionService.updateView(id);
model.addAttribute("question", question);
return "question_detail";
}
수정 코드
updateView()가 question 객체를 return하기 때문에 위와 같이 작성했다.
이후 html 파일을 수정하고 실행하면 정상적으로 실행된다!
방법 2는 오류를 해결하기 위해 내 나름대로 코드를 고치다가 만들어진 방법이다.
방법 2는 updateView 메서드를 만들고 그 안에서 getQuestion()을 사용하는 방식이기 때문에 getQuestion()에서 view를 바로 update해주는 방법 1이 더 효율적이고 클린한 코드라고 생각된다.
빌더 패턴
그룹 스터디 시간에 @Setter를 제거하고 코드를 구현하자는 의견이 나왔고, @Builder에 대한 얘기가 나왔다. 그러고보니 김영한 님의 스프링 입문 강의에서 실무에서는 Setter를 거의 구현하지 않는다는 말을 지나가듯 들었던 것 같다.
Setter를 구현하지 않는 이유는
1. 엉뚱한 곳에서 엔티티의 값을 변경할 위험
2. setter의 남용 위험
3. 생성자를 통해 객체 생성 시 파라미터 순서가 중요하고, 파라미터가 많을수록 가독성이 낮아질 위험
정도로 요약할 수 있을 것 같다.
빌더 패턴 사용하기
@Builder
public class Person {
private String name;
private int age;
}
빌더 패턴을 적용할 객체에 @Builder 어노테이션을 붙인다.
Person person = Person.builder()
.name("yurison")
.age(30)
.build();
객체.builder() ... build(); 이런 방식으로 객체를 생성할 수 있다.
https://2jinishappy.tistory.com/337
https://cocoon1787.tistory.com/708
(스터디 시간에 참고했던 블로그 글들)
'프로젝트 & TIL > 일별 공부 기록 (백엔드 스쿨)' 카테고리의 다른 글
28일차 - @RequestScope (0) | 2023.03.31 |
---|---|
27일차 - MockMvc, tailwind&Daisy UI, Toastr, @Transactional, Git 명령어 (0) | 2023.03.30 |
25일차 - Git Bash 명령어 (0) | 2023.03.28 |
24일차 - Git bash 명령어 (0) | 2023.03.27 |
23일차 - 점프 투 스프링부트 3장(2) (0) | 2023.03.23 |