게시물 조회 기능을 추가해봤다.
@Query로 구현한다.
먼저 엔티티에 조회수를 카운팅할 변수를 선언한다.
[Entity]
@ToString
@Setter
@Getter
@Entity
public class Recipe extends BaseEntity {
...
// 조회수 업데이트
@Column(columnDefinition = "integer default 0", nullable = false)
private int view;
...
}
- columnDefinition (DDL) : 데이터베이스 컬럼 정보를 직접 줄 수 있다.
- Spring Boot에서 JPA Repository를 이용하여 SQL CRUD를 사용할 때, Entity를 이용하여 가져올 데이터를 구성한다.
- 이때 특정 필드의 타입을 지정하여 데이터를 추출할 수 있다.
다음은 Repository에 추가한다.
[Repository]
public interface RecipeRepository extends JpaRepository<Recipe, Long>, QuerydslPredicateExecutor<Recipe>, RecipeRepositoryCustom {
...
// 조회수 카운팅
@Modifying
@Query("update Recipe r set r.view = r.view + 1 where r.id = :id")
int updateView(Long id);
}
- @Modifying : @Query 어노테이션으로 작성된 변경, 삭제 쿼리 메서드를 사용할 때 필요하다.
- 즉, 조회 쿼리를 제회하고, 데이터 변경이 일어나는 INSERT, UPDATE, DELETE에서 사용된다.
- 여기선 UPDATE를 사용했다.
- 게시물 엔티티의 view 속성을 +1로 update 한다.
다음은 Service에 추가한다.
[Service]
// 조회수 카운팅
@Transactional
public int updateView(Long id) {
return recipeRepository.updateView(id);
}
다음은 Controller에 추가한다. (거의 다 왔다.)
[Controller]
@GetMapping(value = "/recipe/{recipeId}")
public String recipeDtl(Model model, @PathVariable("recipeId") Long recipeId) {
RecipeFormDto recipeFormDto = recipeService.getRecipeDtl(recipeId);
recipeService.updateView(recipeId); // views ++
model.addAttribute("recipe", recipeFormDto);
return "recipe/recipeDtl";
}
- 게시글 페이지를 호출할 때마다 updateView(view 변수 1 증가)를 실행한다.
- 실행한 결과를 게시글 페이지에 담아(model) 넘긴다.
마지막으로 ViewPage를 수정하자.
난 Thymeleaf로 했다.
[Thymeleaf]
<div class="text-right">
<div class="h4 text-left">
<input type="hidden" th:value="${recipe.view}" id="view" name="view">
조회수<br>
<span th:text="${recipe.view}"></span>
</div>
</div>
- 조회수 view를 출력한다.
결과는
- 새로고침하면 update 되어 잘 나온다.
쿼리는 어떻게 나갈까?
- 동일한 id일 때, update view + 1이 잘 나간다.
'프로젝트' 카테고리의 다른 글
Custom Exception 해보기 (0) | 2023.02.19 |
---|---|
[JPA/Thymeleaf] 게시글 작성자만 수정 권한 가지기 (0) | 2023.02.18 |
CRUD를 분석해보자 (2) - 게시글 수정/삭제/조회 API (0) | 2023.02.11 |
CRUD를 분석해보자 (1) - 게시글 생성 API (0) | 2023.02.11 |
Spring Security를 이용하여 로그인을 구현해보자 (0) | 2023.01.26 |