DiscussionCommentRepositoryImpl.java
package qwerty.chaekit.domain.group.activity.discussion.comment.repository;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import qwerty.chaekit.domain.group.activity.discussion.DiscussionStance;
import qwerty.chaekit.domain.group.activity.discussion.comment.DiscussionComment;
import qwerty.chaekit.domain.group.activity.discussion.comment.QDiscussionComment;
import qwerty.chaekit.domain.group.activity.discussion.comment.dto.DiscussionCommentCountDto;
import java.util.*;
import java.util.stream.Collectors;
@Repository
@RequiredArgsConstructor
public class DiscussionCommentRepositoryImpl implements DiscussionCommentRepository {
private final DiscussionCommentJpaRepository commentJpaRepository;
private final JPAQueryFactory queryFactory;
@Override
public DiscussionComment getReferenceById(Long id) {
return commentJpaRepository.getReferenceById(id);
}
@Override
public boolean existsById(Long id) {
return commentJpaRepository.existsById(id);
}
@Override
public Optional<DiscussionComment> findById(Long id) {
return commentJpaRepository.findById(id);
}
@Override
public Optional<DiscussionComment> findByIdWithAuthor(Long id) {
return commentJpaRepository.findByIdWithAuthor(id);
}
@Override
public DiscussionComment save(DiscussionComment discussionComment) {
return commentJpaRepository.save(discussionComment);
}
@Override
public void delete(DiscussionComment discussionComment) {
commentJpaRepository.delete(discussionComment);
}
@Override
public Long countCommentsByDiscussionId(Long discussionId) {
return commentJpaRepository.countByDiscussion_Id(discussionId);
}
@Override
public Map<Long, DiscussionCommentCountDto> countStanceCommentsByDiscussionIds(List<Long> discussionIds) {
QDiscussionComment comment = QDiscussionComment.discussionComment;
List<Tuple> results = queryFactory
.select(
comment.discussion.id,
comment.stance,
comment.count()
)
.from(comment)
.where(comment.discussion.id.in(discussionIds))
.groupBy(comment.discussion.id, comment.stance)
.fetch();
// 가공: Map<discussionId, Map<stance, count>> → Map<discussionId, DTO>
Map<Long, Map<DiscussionStance, Long>> grouped = new HashMap<>();
for (Tuple tuple : results) {
Long id = tuple.get(comment.discussion.id);
DiscussionStance stance = tuple.get(comment.stance);
Long count = tuple.get(comment.count());
grouped
.computeIfAbsent(id, k -> new EnumMap<>(DiscussionStance.class))
.put(stance, count);
}
return grouped.entrySet().stream()
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> {
Map<DiscussionStance, Long> map = e.getValue();
long neutral = map.getOrDefault(DiscussionStance.NEUTRAL, 0L);
long agree = map.getOrDefault(DiscussionStance.AGREE, 0L);
long disagree = map.getOrDefault(DiscussionStance.DISAGREE, 0L);
return DiscussionCommentCountDto.ofStanceCounts(neutral, agree, disagree);
}
));
}
@Override
public Map<Long, DiscussionCommentCountDto> countCommentsByDiscussionIds(List<Long> discussionIds) {
QDiscussionComment comment = QDiscussionComment.discussionComment;
return queryFactory
.select(comment.discussion.id, comment.count())
.from(comment)
.where(comment.discussion.id.in(discussionIds))
.groupBy(comment.discussion.id)
.fetch()
.stream()
.collect(Collectors.toMap(
tuple -> tuple.get(comment.discussion.id),
tuple -> DiscussionCommentCountDto.ofSingle(
Optional.ofNullable(tuple.get(comment.count())).orElse(0L)
)
));
}
@Override
public Long countByParentId(Long parentId) {
return commentJpaRepository.countByParent_Id(parentId);
}
@Override
public Optional<DiscussionComment> findByIdWithParent(Long id) {
return commentJpaRepository.findByIdWithRepliesAndParent(id);
}
}