[Spring] 작성한 리뷰 평균 별점 계산 및 별점순 정렬하기 (QueryDSL 사용)

Miin·2023년 11월 27일
0

Spring

목록 보기
14/17
post-custom-banner

⭐ 평균 별점 계산하기

장소 Entity

@Entity
@Setter
@Getter
@Table(name = "tourspot_table")
public class TourspotEntity {
    @Id // pk 지정
    @Column(unique = true, nullable = false, name = "tourspot_id")
    private int tourspotId;
    
    ...(생략)
    
    @Column(columnDefinition = "float default 0")
    private  float tourspotStar;
    
}

리뷰 DTO

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class CommentDTO {

    private int spotCmntId; // 댓글 아이디
    private int spotId; // 게시글(장소) 아이디
    private int categoryNumber;
    private Long userId; // 댓글 작성자
    private String cmntContent; // 내용
    private String cmntImg; // 사진
    private Date cmntTime; // 작성시간
    private int cmntStar; // 평점
}

리뷰 작성 Controller

	// 리뷰 별점을 계산하고 저장한다.
    tourService.calculateAvgStar(commentDTO);

리뷰 Service

	// 평균 별점을 계산하고 저장하는 메소드
    public void calculateAvgStar(CommentDTO commentDTO) {
        int spotId = commentDTO.getSpotId();

        List<SpotCommentEntity> comments = spotCmntRepository.findBySpotId(spotId);

        float totalStars = (float) comments.stream().mapToDouble(SpotCommentEntity::getSpotCmntStar).sum();
        float avgStar = totalStars/comments.size();

        queryFactory.update(tourspotEntity)
                .set(tourspotEntity.tourspotStar, avgStar)
                .where(tourspotEntity.tourspotId.eq(spotId))
                .execute();
    }
  • CommentDTO : 리뷰를 작성한 댓글 DTO
  • getSpotId() : 작성한 리뷰에 해당하는 장소 id
  • findBySpotId(spotId) : spotId에 해당하는 모든 리뷰들을 가져옴
  • comments.stream().mapToDouble(SpotCommentEntity::getSpotCmntStar).sum(); : 앞에서 가져온 모든 리뷰들의 별점값을 가져와 총 별점을 구함
  • totalStars/comments.size() : 총 별점을 모든 리뷰들의 개수로 나누어 평균 별점 계산

queryDSL 이용해 평균 별점 값 업데이트

  • queryFactory.update(tourspotEntity)... : queryFactory를 사용하여 장소 엔티티를 업데이트함
  • .set(tourspotEntity.tourspotStar, avgStar) : 장소 엔티티의 별점 값을 앞에서 구한 평균 별점으로 할당
  • .where(tourspotEntity.tourspotId.eq(spotId)) : spotId와 tourspotId가 같을 경우 업데이트 수행
  • .execute() : 지정된 조건에 맞는 엔티티를 업데이트하여 쿼리 실행

이렇게 장소의 리뷰 댓글들의 평균 별점을 계산하고, 그 값을 업데이트하여 DB에 저장하는 코드를 작성하였다.

이 계산한 평균 별점을 이용하여, 장소들을 별점순으로 정렬해보겠다!


⭐ 별점순 정렬하기

Controller

	List<TourspotEntity> tourlistOrderByStar = tourService.findAllOrderByStar();

장소 엔티티를 별점순으로 정렬한 리스트를 얻음

Service

	public List<TourspotEntity> findAllOrderByStar() {
        return queryFactory.selectFrom(tourspotEntity)
                .orderBy(tourspotEntity.tourspotStar.desc())
                .fetch();
    }

이번에도 queryDSL 사용

  • queryFactory.selectFrom(tourspotEntity) : 데이터베이스에서 장소 엔티티에 해당하는 쿼리 생성
  • .orderBy(tourspotEntity.tourspotStar.desc()) : 장소 엔티티의 별점 필드를 내림차순으로 정렬. 별점을 기준으로 높은 순서대로 정렬함!
  • .fetch() : 정렬된 결과를 가져와서 리스트 형태로 반환


이렇게 별점순으로 정렬하는 것까지 작성해보았다

profile
컴퓨터공학전공 학부생 Back-end Developer
post-custom-banner

0개의 댓글