@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;
}
@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; // 평점
}
// 리뷰 별점을 계산하고 저장한다.
tourService.calculateAvgStar(commentDTO);
// 평균 별점을 계산하고 저장하는 메소드
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
: 리뷰를 작성한 댓글 DTOgetSpotId()
: 작성한 리뷰에 해당하는 장소 idfindBySpotId(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에 저장하는 코드를 작성하였다.
이 계산한 평균 별점을 이용하여, 장소들을 별점순으로 정렬해보겠다!
List<TourspotEntity> tourlistOrderByStar = tourService.findAllOrderByStar();
장소 엔티티를 별점순으로 정렬한 리스트를 얻음
public List<TourspotEntity> findAllOrderByStar() {
return queryFactory.selectFrom(tourspotEntity)
.orderBy(tourspotEntity.tourspotStar.desc())
.fetch();
}
이번에도 queryDSL 사용
queryFactory.selectFrom(tourspotEntity)
: 데이터베이스에서 장소 엔티티에 해당하는 쿼리 생성.orderBy(tourspotEntity.tourspotStar.desc())
: 장소 엔티티의 별점 필드를 내림차순으로 정렬. 별점을 기준으로 높은 순서대로 정렬함!.fetch()
: 정렬된 결과를 가져와서 리스트 형태로 반환이렇게 별점순으로 정렬하는 것까지 작성해보았다