Skip to content

Commit

Permalink
refactor: board, profile을 함께 가져오는 db계층의 로직을 service로 옮긴다.
Browse files Browse the repository at this point in the history
  • Loading branch information
min429 committed Aug 6, 2024
1 parent 415b4a1 commit d333a4c
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.dnd.accompany.domain.accompany.api.dto;

import java.time.LocalDateTime;

import com.dnd.accompany.domain.accompany.entity.enums.Category;
import com.dnd.accompany.domain.accompany.entity.enums.PreferredAge;
import com.dnd.accompany.domain.accompany.entity.enums.PreferredGender;
import com.dnd.accompany.domain.accompany.entity.enums.Region;

public record FindDetailInfoResult(
Long boardId,
String title,
String content,
Region region,
LocalDateTime startDate,
LocalDateTime endDate,
Long headCount,
Long capacity,
Category category,
PreferredAge preferredAge,
PreferredGender preferredGender,
String nickname
) {
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
package com.dnd.accompany.domain.accompany.infrastructure.querydsl;

import static com.dnd.accompany.domain.accompany.entity.QAccompanyBoard.*;
import static com.dnd.accompany.domain.accompany.entity.QAccompanyUser.*;
import static com.dnd.accompany.domain.accompany.entity.enums.Role.*;
import static com.dnd.accompany.domain.user.entity.QUser.*;

import java.util.List;
import java.util.Optional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.SliceImpl;
import org.springframework.stereotype.Repository;

import com.dnd.accompany.domain.accompany.api.dto.AccompanyBoardDetailInfo;
import com.dnd.accompany.domain.accompany.api.dto.AccompanyBoardInfo;
import com.dnd.accompany.domain.accompany.api.dto.ReadAccompanyBoardResponse;
import com.dnd.accompany.domain.accompany.api.dto.UserProfileDetailInfo;
import com.dnd.accompany.domain.accompany.entity.QAccompanyBoard;
import com.dnd.accompany.domain.accompany.entity.QAccompanyUser;
import com.dnd.accompany.domain.accompany.api.dto.FindDetailInfoResult;
import com.dnd.accompany.domain.accompany.infrastructure.querydsl.interfaces.AccompanyBoardRepositoryCustom;
import com.dnd.accompany.domain.user.entity.QUser;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;
Expand All @@ -31,11 +28,12 @@ public class AccompanyBoardRepositoryImpl implements AccompanyBoardRepositoryCus

private final JPAQueryFactory queryFactory;

@Override
public Page<AccompanyBoardInfo> findBoardInfos(Pageable pageable) {
QAccompanyUser accompanyUser = QAccompanyUser.accompanyUser;
QAccompanyBoard accompanyBoard = QAccompanyBoard.accompanyBoard;
public static BooleanExpression isHost() {
return accompanyUser.role.eq(HOST);
}

@Override
public Slice<AccompanyBoardInfo> findBoardInfos(Pageable pageable) {
List<AccompanyBoardInfo> content = queryFactory.select(Projections.constructor(AccompanyBoardInfo.class,
accompanyBoard.id,
accompanyBoard.title,
Expand All @@ -45,64 +43,50 @@ public Page<AccompanyBoardInfo> findBoardInfos(Pageable pageable) {
user.nickname))
.from(accompanyUser)
.join(accompanyUser.accompanyBoard, accompanyBoard)
.join(accompanyUser.user, user) // 추가된 부분
.join(accompanyUser.user, user)
.where(accompanyUser.role.eq(HOST))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.limit(pageable.getPageSize() + 1) // 한 페이지에 하나 더 가져와서 hasNext 체크에 사용
.fetch();

long total = queryFactory.select(accompanyUser.count())
.from(accompanyUser)
.join(accompanyUser.accompanyBoard, accompanyBoard)
.join(accompanyUser.user, user)
.where(accompanyUser.role.eq(HOST))
.fetchOne();
boolean hasNext = false;
if (content.size() > pageable.getPageSize()) {
content.remove(pageable.getPageSize());
hasNext = true;
}

return new PageImpl<>(content, pageable, total);
return new SliceImpl<>(content, pageable, hasNext);
}

/**
* 동행글, 프로필 정보를 한번에 가져옵니다.
*/

@Override
public Optional<ReadAccompanyBoardResponse> findDetailInfo(Long boardId) {
QAccompanyBoard accompanyBoard = QAccompanyBoard.accompanyBoard;
QAccompanyUser accompanyUser = QAccompanyUser.accompanyUser;
QUser user = QUser.user;

Tuple result = queryFactory
.select(Projections.constructor(AccompanyBoardDetailInfo.class,
accompanyBoard.id,
accompanyBoard.title,
accompanyBoard.content,
accompanyBoard.region,
accompanyBoard.startDate,
accompanyBoard.endDate,
accompanyBoard.headCount,
accompanyBoard.capacity,
accompanyBoard.category,
accompanyBoard.preferredAge,
accompanyBoard.preferredGender),
Projections.constructor(UserProfileDetailInfo.class,
user.nickname))
public Optional<FindDetailInfoResult> findDetailInfo(Long boardId) {
FindDetailInfoResult result = queryFactory
.select(Projections.constructor(FindDetailInfoResult.class,
accompanyBoard.id,
accompanyBoard.title,
accompanyBoard.content,
accompanyBoard.region,
accompanyBoard.startDate,
accompanyBoard.endDate,
accompanyBoard.headCount,
accompanyBoard.capacity,
accompanyBoard.category,
accompanyBoard.preferredAge,
accompanyBoard.preferredGender,
user.nickname))
.from(accompanyBoard)
.leftJoin(accompanyUser).on(accompanyUser.accompanyBoard.id.eq(accompanyBoard.id)
.and(accompanyUser.role.eq(HOST)))
.and(isHost()))
.leftJoin(user).on(user.id.eq(accompanyUser.user.id))
.where(accompanyBoard.id.eq(boardId))
.fetchOne();

if (result == null) {
return Optional.empty();
}

AccompanyBoardDetailInfo detailInfo = result.get(0, AccompanyBoardDetailInfo.class);
UserProfileDetailInfo profileInfo = result.get(1, UserProfileDetailInfo.class);

ReadAccompanyBoardResponse response = new ReadAccompanyBoardResponse(detailInfo, profileInfo);
return Optional.ofNullable(result);
}

return Optional.of(response);
@Override
public boolean isHostOfBoard(Long userId, Long boardId) {
Integer fetchCount = queryFactory.selectOne()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

import java.util.Optional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

import com.dnd.accompany.domain.accompany.api.dto.AccompanyBoardInfo;
import com.dnd.accompany.domain.accompany.api.dto.ReadAccompanyBoardResponse;
import com.dnd.accompany.domain.accompany.api.dto.FindDetailInfoResult;

public interface AccompanyBoardRepositoryCustom {
Page<AccompanyBoardInfo> findBoardInfos(Pageable pageable);
Slice<AccompanyBoardInfo> findBoardInfos(Pageable pageable);

Optional<ReadAccompanyBoardResponse> findDetailInfo(Long boardId);
Optional<FindDetailInfoResult> findDetailInfo(Long boardId);

boolean isHostOfBoard(Long userId, Long boardId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
import static com.dnd.accompany.domain.accompany.entity.AccompanyBoard.*;
import static com.dnd.accompany.domain.accompany.entity.enums.Role.*;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dnd.accompany.domain.accompany.api.dto.AccompanyBoardDetailInfo;
import com.dnd.accompany.domain.accompany.api.dto.AccompanyBoardInfo;
import com.dnd.accompany.domain.accompany.api.dto.CreateAccompanyBoardRequest;
import com.dnd.accompany.domain.accompany.api.dto.CreateAccompanyBoardResponse;
import com.dnd.accompany.domain.accompany.api.dto.FindDetailInfoResult;
import com.dnd.accompany.domain.accompany.api.dto.PageResponse;
import com.dnd.accompany.domain.accompany.api.dto.ReadAccompanyBoardResponse;
import com.dnd.accompany.domain.accompany.api.dto.UserProfileDetailInfo;
import com.dnd.accompany.domain.accompany.entity.AccompanyBoard;
import com.dnd.accompany.domain.accompany.exception.AccompanyBoardAccessDeniedException;
import com.dnd.accompany.domain.accompany.exception.AccompanyBoardNotFoundException;
Expand Down Expand Up @@ -57,15 +60,45 @@ public CreateAccompanyBoardResponse create(Long userId, CreateAccompanyBoardRequ
@Transactional(readOnly = true)
public PageResponse<AccompanyBoardInfo> readAll(int page, int size) {
Pageable pageable = PageRequest.of(page, size);
Page<AccompanyBoardInfo> pageResult = accompanyBoardRepository.findBoardInfos(pageable);
Slice<AccompanyBoardInfo> sliceResult = accompanyBoardRepository.findBoardInfos(pageable);

return new PageResponse<>(pageResult.hasNext(), pageResult.getContent());
return new PageResponse<>(sliceResult.hasNext(), sliceResult.getContent());
}

@Transactional(readOnly = true)
public ReadAccompanyBoardResponse read(Long boardId) {
return accompanyBoardRepository.findDetailInfo(boardId)
FindDetailInfoResult detailInfo = accompanyBoardRepository.findDetailInfo(boardId)
.orElseThrow(() -> new AccompanyBoardNotFoundException(ErrorCode.ACCOMPANY_BOARD_NOT_FOUND));

AccompanyBoardDetailInfo accompanyBoardDetailInfo = getAccompanyBoardDetailInfo(
detailInfo);

UserProfileDetailInfo userProfileDetailInfo = getUserProfileDetailInfo(
detailInfo);

return new ReadAccompanyBoardResponse(accompanyBoardDetailInfo, userProfileDetailInfo);
}

private static UserProfileDetailInfo getUserProfileDetailInfo(FindDetailInfoResult detailInfo) {
return UserProfileDetailInfo.builder()
.nickname(detailInfo.nickname())
.build();
}

private static AccompanyBoardDetailInfo getAccompanyBoardDetailInfo(FindDetailInfoResult detailInfo) {
return AccompanyBoardDetailInfo.builder()
.boardId(detailInfo.boardId())
.title(detailInfo.title())
.content(detailInfo.content())
.region(detailInfo.region())
.startDate(detailInfo.startDate())
.endDate(detailInfo.endDate())
.headCount(detailInfo.headCount())
.capacity(detailInfo.capacity())
.category(detailInfo.category())
.preferredAge(detailInfo.preferredAge())
.preferredGender(detailInfo.preferredGender())
.build();
}

@Transactional
Expand Down

0 comments on commit d333a4c

Please sign in to comment.