Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Academy schedules] LikeAccessService를 Facade 패턴으로 변경 및 N+1 문제 개선 #126

Merged
merged 10 commits into from
Dec 9, 2023
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import org.guzzing.studayserver.domain.academy.controller.dto.response.LessonInfoToCreateDashboardResponses;
import org.guzzing.studayserver.domain.academy.facade.AcademyFacade;
import org.guzzing.studayserver.domain.academy.facade.dto.AcademiesByLocationWithScrollFacadeResult;
import org.guzzing.studayserver.domain.academy.facade.dto.AcademyDetailFacadeParam;
import org.guzzing.studayserver.domain.academy.facade.dto.AcademyDetailFacadeResult;
import org.guzzing.studayserver.domain.academy.service.AcademyService;
import org.guzzing.studayserver.domain.academy.service.dto.result.AcademiesByNameResults;
import org.guzzing.studayserver.domain.academy.service.dto.result.AcademiesFilterWithScrollResults;
Expand Down Expand Up @@ -44,8 +46,10 @@ public ResponseEntity<AcademyGetResponse> getAcademy(
@PathVariable Long academyId,
@MemberId Long memberId
) {
AcademyDetailFacadeResult detailAcademy = academyFacade.getDetailAcademy(AcademyDetailFacadeParam.of(memberId, academyId));

return ResponseEntity.status(HttpStatus.OK)
.body(AcademyGetResponse.from(academyService.getAcademy(academyId, memberId)));
.body(AcademyGetResponse.from(detailAcademy));
}

@GetMapping(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.guzzing.studayserver.domain.academy.controller.dto.response;

import java.util.List;

import org.guzzing.studayserver.domain.academy.facade.dto.AcademyDetailFacadeResult;
import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyGetResult;

public record AcademyGetResponse(
Expand All @@ -16,7 +18,7 @@ public record AcademyGetResponse(
boolean isLiked
) {

public static AcademyGetResponse from(AcademyGetResult academyGetResult) {
public static AcademyGetResponse from(AcademyDetailFacadeResult academyGetResult) {
return new AcademyGetResponse(
academyGetResult.academyName(),
academyGetResult.contact(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import org.guzzing.studayserver.domain.academy.facade.dto.AcademiesByLocationWithScrollFacadeParam;
import org.guzzing.studayserver.domain.academy.facade.dto.AcademiesByLocationWithScrollFacadeResult;
import org.guzzing.studayserver.domain.academy.facade.dto.AcademyDetailFacadeParam;
import org.guzzing.studayserver.domain.academy.facade.dto.AcademyDetailFacadeResult;
import org.guzzing.studayserver.domain.academy.service.AcademyService;
import org.guzzing.studayserver.domain.academy.service.dto.result.AcademiesByLocationWithScrollResults;
import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyGetResult;
import org.guzzing.studayserver.domain.academy.util.GeometryUtil;
import org.guzzing.studayserver.domain.like.service.LikeService;
import org.guzzing.studayserver.domain.region.service.RegionService;
import org.guzzing.studayserver.domain.region.service.dto.location.RegionResult;
import org.springframework.stereotype.Service;
Expand All @@ -14,10 +18,12 @@ public class AcademyFacade {

private final RegionService regionService;
private final AcademyService academyService;
private final LikeService likeService;

public AcademyFacade(RegionService regionService, AcademyService academyService) {
public AcademyFacade(RegionService regionService, AcademyService academyService, LikeService likeService) {
this.regionService = regionService;
this.academyService = academyService;
this.likeService = likeService;
}

public AcademiesByLocationWithScrollFacadeResult findByLocationWithScroll(AcademiesByLocationWithScrollFacadeParam param) {
Expand All @@ -29,7 +35,16 @@ public AcademiesByLocationWithScrollFacadeResult findByLocationWithScroll(Academ
param.lat(),
param.lng()));

return AcademiesByLocationWithScrollFacadeResult.from(academiesByLocationWithScroll, regionContainingPoint);
return AcademiesByLocationWithScrollFacadeResult.from(
academiesByLocationWithScroll,
regionContainingPoint);
}

public AcademyDetailFacadeResult getDetailAcademy(AcademyDetailFacadeParam param) {
AcademyGetResult academyGetResult = academyService.getAcademy(param.academyId());
boolean liked = likeService.isLiked(param.academyId(), param.memberId());

return AcademyDetailFacadeResult.of(academyGetResult, liked);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ public static AcademiesByLocationWithScrollFacadeResult from(
academiesByLocationResults
.academiesByLocationResults()
.stream()
.map(academyByLocationResult ->
AcademyByLocationWithScrollFacadeResult.from(academyByLocationResult))
.map(AcademyByLocationWithScrollFacadeResult::from)
.toList(),
regionResult.sido(),
regionResult.sigungu(),
Expand Down Expand Up @@ -58,6 +57,3 @@ public static AcademyByLocationWithScrollFacadeResult from(

}
}



Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.guzzing.studayserver.domain.academy.facade.dto;

public record AcademyDetailFacadeParam(
Long memberId,
Long academyId
) {

public static AcademyDetailFacadeParam of(Long memberId, Long academyId) {
return new AcademyDetailFacadeParam(
memberId,
academyId
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.guzzing.studayserver.domain.academy.facade.dto;

import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyGetResult;
import org.guzzing.studayserver.domain.academy.service.dto.result.LessonGetResults;
import org.guzzing.studayserver.domain.academy.service.dto.result.ReviewPercentGetResult;

import java.util.List;

public record AcademyDetailFacadeResult(
String academyName,
String contact,
String fullAddress,
String shuttleAvailability,
Long expectedFee,
String updatedDate,
LessonGetResults lessonGetResults,
ReviewPercentGetResult reviewPercentGetResult,
List<String> categories,
boolean isLiked
) {

public static AcademyDetailFacadeResult of(AcademyGetResult academyGetResult, boolean isLiked) {
return new AcademyDetailFacadeResult(
academyGetResult.academyName(),
academyGetResult.contact(),
academyGetResult.fullAddress(),
academyGetResult.shuttleAvailability(),
academyGetResult.expectedFee(),
academyGetResult.updatedDate(),
academyGetResult.lessonGetResults(),
academyGetResult.reviewPercentGetResult(),
academyGetResult.categories(),
isLiked
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ public AcademiesByLocationWithScroll findAcademiesByLocation(
a.latitude AS latitude,
a.longitude AS longitude,
a.shuttle AS shuttleAvailable,
(CASE WHEN l.academy_id IS NOT NULL THEN true ELSE false END) AS isLiked
(CASE WHEN l.academy_id IS NOT NULL THEN true ELSE false END) AS isLiked,
ac.category_id AS categoryId
FROM
academies AS a
INNER JOIN
academy_categories AS ac ON a.id = ac.academy_id
LEFT JOIN
likes AS l ON a.id = l.academy_id AND l.member_id = %s """;

Expand All @@ -64,6 +67,7 @@ public AcademiesByLocationWithScroll findAcademiesByLocation(
.addScalar("longitude", StandardBasicTypes.DOUBLE)
.addScalar("shuttleAvailable", StandardBasicTypes.STRING)
.addScalar("isLiked", StandardBasicTypes.BOOLEAN)
.addScalar("categoryId",StandardBasicTypes.LONG)
.setResultTransformer((tuple, aliases) -> new AcademyByLocationWithScroll(
(Long) tuple[0],
(String) tuple[1],
Expand All @@ -72,7 +76,8 @@ public AcademiesByLocationWithScroll findAcademiesByLocation(
(Double) tuple[4],
(Double) tuple[5],
(String) tuple[6],
(boolean) tuple[7]
(boolean) tuple[7],
(Long) tuple[8]
))
.getResultList();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,54 @@
package org.guzzing.studayserver.domain.academy.repository.dto;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public record AcademiesByLocationWithScroll(
List<AcademyByLocationWithScroll> academiesByLocation,
Map<AcademyByLocation,List<Long>> academiesByLocation,
boolean hasNext
) {

public static AcademiesByLocationWithScroll of(
List<AcademyByLocationWithScroll> academiesByLocation,
boolean hasNext
) {
Map<AcademyByLocation, List<Long>> academyIdWithCategories = new ConcurrentHashMap<>();

academiesByLocation.forEach(academyByLocationWithScroll -> {
academyIdWithCategories.computeIfAbsent(AcademyByLocation.of(academyByLocationWithScroll), k -> new ArrayList<>())
.add(academyByLocationWithScroll.categoryId());
});

return new AcademiesByLocationWithScroll(
academiesByLocation,
academyIdWithCategories,
hasNext
);
}
public record AcademyByLocation(
Long academyId,
String academyName,
String fullAddress,
String phoneNumber,
Double latitude,
Double longitude,
String shuttleAvailable,
boolean isLiked
) {
public static AcademyByLocation of(AcademyByLocationWithScroll academyByLocationWithScroll) {
return new AcademyByLocation(
academyByLocationWithScroll.academyId(),
academyByLocationWithScroll.academyName(),
academyByLocationWithScroll.fullAddress(),
academyByLocationWithScroll.phoneNumber(),
academyByLocationWithScroll.latitude(),
academyByLocationWithScroll.longitude(),
academyByLocationWithScroll.shuttleAvailable(),
academyByLocationWithScroll.isLiked()
);
}
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.guzzing.studayserver.domain.academy.repository.dto;

import java.util.Objects;

public record AcademyByLocationWithScroll(
Long academyId,
String academyName,
Expand All @@ -8,7 +10,7 @@ public record AcademyByLocationWithScroll(
Double latitude,
Double longitude,
String shuttleAvailable,
boolean isLiked
boolean isLiked,
Long categoryId
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import org.guzzing.studayserver.domain.academy.repository.dto.AcademiesByFilterWithScroll;
import org.guzzing.studayserver.domain.academy.repository.dto.AcademiesByLocationWithScroll;
import org.guzzing.studayserver.domain.academy.repository.dto.AcademyByFilterWithScroll;
import org.guzzing.studayserver.domain.academy.repository.dto.AcademyByLocationWithScroll;
import org.guzzing.studayserver.domain.academy.repository.lesson.LessonRepository;
import org.guzzing.studayserver.domain.academy.repository.review.ReviewCountRepository;
import org.guzzing.studayserver.domain.academy.service.dto.param.AcademiesByLocationWithScrollParam;
Expand All @@ -23,7 +22,6 @@
import org.guzzing.studayserver.domain.academy.service.dto.result.AcademyGetResult;
import org.guzzing.studayserver.domain.academy.service.dto.result.LessonInfoToCreateDashboardResults;
import org.guzzing.studayserver.domain.academy.util.GeometryUtil;
import org.guzzing.studayserver.domain.like.service.LikeAccessService;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -37,26 +35,23 @@ public class AcademyService {
private final AcademyRepository academyRepository;
private final LessonRepository lessonRepository;
private final ReviewCountRepository reviewCountRepository;
private final LikeAccessService likeAccessService;
private final AcademyCategoryRepository academyCategoryRepository;

public AcademyService(AcademyRepository academyRepository, LessonRepository lessonRepository,
ReviewCountRepository reviewCountRepository, LikeAccessService likeAccessService,
ReviewCountRepository reviewCountRepository,
AcademyCategoryRepository academyCategoryRepository) {
this.academyRepository = academyRepository;
this.lessonRepository = lessonRepository;
this.reviewCountRepository = reviewCountRepository;
this.likeAccessService = likeAccessService;
this.academyCategoryRepository = academyCategoryRepository;
}

@Transactional(readOnly = true)
public AcademyGetResult getAcademy(Long academyId, Long memberId) {
public AcademyGetResult getAcademy(Long academyId) {
return AcademyGetResult.from(
academyRepository.getById(academyId),
lessonRepository.findAllByAcademyId(academyId),
reviewCountRepository.getByAcademyId(academyId),
isLiked(academyId, memberId),
academyCategoryRepository.findCategoryIdsByAcademyId(academyId));
}

Expand All @@ -70,27 +65,8 @@ public AcademiesByLocationWithScrollResults findAcademiesByLocationWithScroll(Ac
param.pageNumber(),
ACADEMY_LOCATION_SEARCH_PAGE_SIZE);

Map<Long, List<Long>> academyIdWithCategories
= makeCategoriesWithLocationScroll(academiesByLocation.academiesByLocation());

return AcademiesByLocationWithScrollResults.to(
academiesByLocation,
academyIdWithCategories);
}

private Map<Long, List<Long>> makeCategoriesWithLocationScroll(
List<AcademyByLocationWithScroll> academiesByLocations) {
Map<Long, List<Long>> academyIdWithCategories = new ConcurrentHashMap<>();
academiesByLocations.forEach(
academyByLocationWithScroll -> {
academyIdWithCategories.put(
academyByLocationWithScroll.academyId(),
academyCategoryRepository.findCategoryIdsByAcademyId(
academyByLocationWithScroll.academyId()));
}
);

return academyIdWithCategories;
academiesByLocation);
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -131,10 +107,6 @@ private Map<Long, List<Long>> makeCategoriesByFilterWithScroll(
return academyIdWithCategories;
}

private boolean isLiked(Long academyId, Long memberId) {
return likeAccessService.isLiked(academyId, memberId);
}

@Transactional(readOnly = true)
public LessonInfoToCreateDashboardResults getLessonsInfoAboutAcademy(Long academyId) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,18 @@ public record AcademiesByLocationWithScrollResults(
) {

public static AcademiesByLocationWithScrollResults to(
AcademiesByLocationWithScroll academiesByLocationWithScroll,
Map<Long, List<Long>> academyIdWithCategories) {
AcademiesByLocationWithScroll academiesByLocationWithScroll) {
return new AcademiesByLocationWithScrollResults(
academiesByLocationWithScroll
.academiesByLocation()
.stream()
.map(
academyByLocationWithScroll ->
AcademiesByLocationResultWithScroll.from(
academyByLocationWithScroll,
academyIdWithCategories.get(academyByLocationWithScroll.academyId())
))
.toList(),
.keySet()
.stream()
.map(academyByLocation->
AcademiesByLocationResultWithScroll.from(
academyByLocation,
academiesByLocationWithScroll.academiesByLocation().
get(academyByLocation)))
.toList(),
academiesByLocationWithScroll.hasNext());
}

Expand All @@ -40,15 +39,15 @@ public record AcademiesByLocationResultWithScroll(
boolean isLiked
) {

public static AcademiesByLocationResultWithScroll from(AcademyByLocationWithScroll academyByLocationWithScroll,
List<Long> categories) {
public static AcademiesByLocationResultWithScroll from(AcademiesByLocationWithScroll.AcademyByLocation academyByLocationWithScroll,
List<Long> categories) {
return new AcademiesByLocationResultWithScroll(
academyByLocationWithScroll.academyId(),
academyByLocationWithScroll.academyName(),
academyByLocationWithScroll.fullAddress(),
academyByLocationWithScroll.phoneNumber(),
categories.stream()
.map(categoryId -> CategoryInfo.getCategoryNameById(categoryId))
.map(CategoryInfo::getCategoryNameById)
.toList(),
academyByLocationWithScroll.latitude(),
academyByLocationWithScroll.longitude(),
Expand Down
Loading