SpringBoot + MariaDB 9-1 기타기능 인기페이지
인기페이지
인기페이지란 좋아요가 있는 사진들을 보여주는 곳이다
요청을 받을컨트롤러
인기페이지 요청을받아 인기사진들을 반환하도록 설정
web.ImageController.java
@GetMapping("/image/popular")
public String popular(Model model) {
List<Image> images = imageService.인기사진();
model.addAttribute("images",images);
return "image/popular";
}
인기사진 서비스의 함수
service.ImageService.java
@Transactional(readOnly = true)
public List<Image> 인기사진() {
return imageRepository.mPopular();
}
쿼리문 만들기
이제 db에 요청을 할려면 쿼리문을 작성해야하는데 완성된 쿼리문은 이러하다
SELECT i.*
FROM image i
INNER JOIN (SELECT imageId,COUNT(imageId) likeCount FROM likes group by imageId) c
on i.id = c.imageId
ORDER BY likeCount DESC;
SELECT * FROM image WHERE id IN(SELECT imageId FROM(SELECT imageId,COUNT(imageId) likeCount FROM likes group by imageId ORDER BY likeCount DESC) c);
처음에 작성한 코드는 in을 이용하여 안에 서브쿼리로 좋아요가 많은순으로 적용을하였다
하지만 in은 3,2값이 입력되더라도 2와 3의 값이 알아서 정렬되서 desc순으로 받아올수가 없어 수정하게되었다
예를 들어 3,2번값이 in에 들어왔다하면 3번을 1row로 가는게 아니라 2번을 1row에 출력하고 3번을 2row에 출력해서 desc가 불가능하다
조인에 서브쿼리를 넣어 조인시켜 결과를 합쳐 출력하고
이대로 가져오게된다면 에러가난다 왜? 당연히 image에는 imageId와 likeCount라는 멤버가 없으니까 그렇다면 만들어줘야하나요? 아니다 굳이 가져와도 쓸대가없기때문에 필요한 image의 데이터만 가져오기위해 i.*을이용해 image만 데이터를 뽑아내면 결과는 이러하다.
이제 원하는대로 데이터를 뽑았으니 db문에 적용시켜보자
db요청
domain.image.ImageRepository.java
밑과같이 코드 추가해주기
@Query(value="SELECT i.* FROM image i INNER JOIN (SELECT imageId,COUNT(imageId) likeCount FROM likes group by imageId) c on i.id = c.imageId ORDER BY likeCount DESC",nativeQuery = true)
List<Image> mPopular();
popular.jsp
이제 jsp파일에서 c:forEach로 출력해주자.
<c:forEach var="image" items="${images }">
<div class="p-img-box">
<a href="/user/${image.user.id }"> <img src="/upload/${image.postImageUrl }" />
</a>
</div>
</c:forEach>