From d9180034d09575bca342872e8906e1c1a732220d Mon Sep 17 00:00:00 2001 From: HyeonJun An Date: Fri, 22 Sep 2023 02:38:44 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[LH-195]=20filtering=20=EA=B8=B0=ED=9A=8D?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20=EC=A0=81=EC=9A=A9=20(#43)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lingoswap/match/api/MatchController.java | 23 +++++------- .../MatchedMemberQueryRepository.java | 16 +++++++-- .../repository/MatchedMemberRepository.java | 35 +++++++++---------- .../match/service/FilterService.java | 20 ----------- .../lingoswap/match/service/MatchManager.java | 20 ++++++----- .../lingoswap/match/service/MatchService.java | 12 +++++-- .../member/dto/MemberProfileResponse.java | 2 +- .../member/service/MemberManager.java | 2 +- .../question/api/QuestionController.java | 6 ++-- .../dto/QuestionDeleteLikeRequest.java | 2 +- .../question/dto/QuestionDetail.java | 4 +-- .../dto/QuestionUpdateLikeRequest.java | 2 +- .../question/service/QuestionManager.java | 8 ++--- 13 files changed, 70 insertions(+), 82 deletions(-) delete mode 100644 src/main/java/com/lighthouse/lingoswap/match/service/FilterService.java diff --git a/src/main/java/com/lighthouse/lingoswap/match/api/MatchController.java b/src/main/java/com/lighthouse/lingoswap/match/api/MatchController.java index c797c8b..8c03c9d 100644 --- a/src/main/java/com/lighthouse/lingoswap/match/api/MatchController.java +++ b/src/main/java/com/lighthouse/lingoswap/match/api/MatchController.java @@ -1,18 +1,12 @@ package com.lighthouse.lingoswap.match.api; +import com.lighthouse.lingoswap.common.dto.ResponseDto; +import com.lighthouse.lingoswap.match.dto.MatchedMemberProfilesResponse; import com.lighthouse.lingoswap.match.service.MatchManager; -import com.lighthouse.lingoswap.member.dto.MemberSimpleProfile; -import com.lighthouse.lingoswap.member.entity.Member; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RequiredArgsConstructor @RestController @@ -22,12 +16,11 @@ public class MatchController { private final MatchManager matchManager; @Transactional - @GetMapping("/{user_id}/matches") - public ResponseEntity> get(@PathVariable final String uuid - , @PageableDefault(size = 10, sort = "id") Pageable pageable) { - Slice slice = matchManager.read(uuid, pageable); - Slice sliceDto = slice.map(MemberSimpleProfile::from); + @GetMapping(path = "/{uuid}/matches") + public ResponseEntity> get(@PathVariable final String uuid, + @RequestParam(required = false) Long next, + @RequestParam(defaultValue = "10") final int pageSize) { - return ResponseEntity.ok(sliceDto); + return ResponseEntity.ok(matchManager.read(uuid, next, pageSize)); } } diff --git a/src/main/java/com/lighthouse/lingoswap/match/repository/MatchedMemberQueryRepository.java b/src/main/java/com/lighthouse/lingoswap/match/repository/MatchedMemberQueryRepository.java index 43f9ee4..fcd4eb4 100644 --- a/src/main/java/com/lighthouse/lingoswap/match/repository/MatchedMemberQueryRepository.java +++ b/src/main/java/com/lighthouse/lingoswap/match/repository/MatchedMemberQueryRepository.java @@ -1,10 +1,20 @@ package com.lighthouse.lingoswap.match.repository; +import com.lighthouse.lingoswap.common.dto.SliceDto; +import com.lighthouse.lingoswap.match.entity.MatchedMember; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; import org.springframework.stereotype.Repository; +import java.util.List; + +import static com.lighthouse.lingoswap.match.entity.QMatchedMember.matchedMember; +import static com.lighthouse.lingoswap.member.entity.QMember.member; + @Repository public class MatchedMemberQueryRepository { -/* + private final JPAQueryFactory queryFactory; public MatchedMemberQueryRepository(EntityManager em) { @@ -38,6 +48,6 @@ private Long removeLastAndReturnNextIdByPageSize(final List match matchedMembers.remove(pageSize); lastId = matchedMembers.get(pageSize - 1).getId(); } - return lastId;*/ - + return lastId; + } } diff --git a/src/main/java/com/lighthouse/lingoswap/match/repository/MatchedMemberRepository.java b/src/main/java/com/lighthouse/lingoswap/match/repository/MatchedMemberRepository.java index 07e820e..f358635 100644 --- a/src/main/java/com/lighthouse/lingoswap/match/repository/MatchedMemberRepository.java +++ b/src/main/java/com/lighthouse/lingoswap/match/repository/MatchedMemberRepository.java @@ -13,50 +13,47 @@ public interface MatchedMemberRepository extends JpaRepository { @Modifying(clearAutomatically = true) - @Query(value = "DELETE FROM filtered_member as mm WHERE mm.from_member_id = :memberId", nativeQuery = true) - void deletePreviousFilteredMember(@Param("memberId") Long memberId); + @Query(value = "DELETE FROM matched_member as mm WHERE mm.from_member_id = :memberId", nativeQuery = true) + void deletePreviousMatchedMember(@Param("memberId") Long memberId); @Modifying(clearAutomatically = true) @Query(value = """ - INSERT INTO filtered_member(from_member_id, to_member_id) + INSERT INTO matched_member(from_member_id, to_member_id) SELECT :memberId, sub.mm_id FROM ( SELECT - mm.to_member_id AS mm_id, + m.id AS mm_id, IF(m.region_id in (:preferredCountryIds), 20,0) AS score - FROM matched_member mm - JOIN Member m ON mm.to_member_id = m.id + FROM Member m LEFT JOIN preferred_country pc ON m.id = pc.member_id - WHERE mm.from_member_id = :memberId + WHERE m.id != :memberId UNION ALL SELECT - mm.to_member_id AS mm_id, + m.id AS mm_id, IF(ul.language_id IN (:languageIds), 5, 0) AS score - FROM matched_Member mm - JOIN Member m ON mm.to_member_id = m.id - JOIN used_language ul ON m.id = ul.member_id - WHERE mm.from_member_id = :memberId + FROM Member m + LEFT JOIN used_language ul ON m.id = ul.member_id + WHERE m.id != :memberId UNION ALL SELECT - mm.to_member_id AS mm_id, + m.id AS mm_id, IF(i.category_id IN (:categoryIds) ,1 ,0) AS score - FROM matched_member mm - JOIN Member m ON mm.to_member_id = m.id - JOIN preferred_interests pi ON m.id = pi.member_id - JOIN interests i ON pi.interests_id = i.id - WHERE mm.from_member_id = :memberId + FROM Member m + LEFT JOIN preferred_interests pi ON m.id = pi.member_id + LEFT JOIN interests i ON pi.interests_id = i.id + WHERE m.id != :memberId ) AS sub GROUP BY sub.mm_id ORDER BY SUM(sub.score) DESC """, nativeQuery = true) - void saveFilteredMembersWithPreferences( + void saveMatchedMembersWithPreferences( @Param("memberId") Long memberId, @Param("preferredCountryIds") List preferredCountryIds, @Param("languageIds") List preferredLanguages, diff --git a/src/main/java/com/lighthouse/lingoswap/match/service/FilterService.java b/src/main/java/com/lighthouse/lingoswap/match/service/FilterService.java deleted file mode 100644 index 689ffee..0000000 --- a/src/main/java/com/lighthouse/lingoswap/match/service/FilterService.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.lighthouse.lingoswap.match.service; - -import com.lighthouse.lingoswap.match.entity.FilteredMember; -import com.lighthouse.lingoswap.match.repository.FilteredMemberRepository; -import com.lighthouse.lingoswap.member.entity.Member; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.stereotype.Service; - -@RequiredArgsConstructor -@Service -public class FilterService { - - private final FilteredMemberRepository filteredMemberRepository; - - public Slice findFilteredMembers(Member member, Pageable pageable) { - return filteredMemberRepository.findByFromMember(member, pageable); - } -} diff --git a/src/main/java/com/lighthouse/lingoswap/match/service/MatchManager.java b/src/main/java/com/lighthouse/lingoswap/match/service/MatchManager.java index 9d906a6..198429c 100644 --- a/src/main/java/com/lighthouse/lingoswap/match/service/MatchManager.java +++ b/src/main/java/com/lighthouse/lingoswap/match/service/MatchManager.java @@ -1,6 +1,10 @@ package com.lighthouse.lingoswap.match.service; -import com.lighthouse.lingoswap.match.entity.FilteredMember; +import com.lighthouse.lingoswap.common.dto.ResponseDto; +import com.lighthouse.lingoswap.common.dto.SliceDto; +import com.lighthouse.lingoswap.match.dto.MatchedMemberProfilesResponse; +import com.lighthouse.lingoswap.match.entity.MatchedMember; +import com.lighthouse.lingoswap.member.dto.MemberSimpleProfile; import com.lighthouse.lingoswap.member.entity.*; import com.lighthouse.lingoswap.member.service.MemberService; import com.lighthouse.lingoswap.member.service.PreferredCountryService; @@ -8,8 +12,6 @@ import com.lighthouse.lingoswap.member.service.UsedLanguageService; import com.lighthouse.lingoswap.question.entity.Category; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; import org.springframework.stereotype.Service; import java.util.List; @@ -19,15 +21,14 @@ public class MatchManager { private final MatchService matchService; - private final FilterService filterService; private final MemberService memberService; private final PreferredCountryService preferredCountryService; private final UsedLanguageService usedLanguageService; private final PreferredInterestsService preferredInterestsService; - public Slice read(final String uuid, Pageable pageable) { + public ResponseDto read(final String uuid, final Long nextId, final int pageSize) { Member fromMember = memberService.findByUuid(uuid); - if (pageable.getPageNumber() == 0) { + if (nextId == null) { List usedLanguageIds = usedLanguageService.findByMember(fromMember) .stream() .map(UsedLanguage::getId) @@ -45,12 +46,13 @@ public Slice read(final String uuid, Pageable pageable) { .map(Category::getId) .toList(); - matchService.saveFilteredMembersWithPreferences( + matchService.saveMatchedMembersWithPreferences( fromMember.getId(), preferredCountryIds, usedLanguageIds, categoryIds); } - Slice filteredMembers = filterService.findFilteredMembers(fromMember, pageable); - return filteredMembers.map(FilteredMember::getToMember); + SliceDto matchedMembers = matchService.findFilteredMembers(fromMember.getId(), nextId, pageSize); + List results = matchedMembers.content().stream().map(MatchedMember::getToMember).map(MemberSimpleProfile::from).toList(); + return ResponseDto.success(new MatchedMemberProfilesResponse(matchedMembers.nextId(), results)); } } diff --git a/src/main/java/com/lighthouse/lingoswap/match/service/MatchService.java b/src/main/java/com/lighthouse/lingoswap/match/service/MatchService.java index 8548309..41d15d6 100644 --- a/src/main/java/com/lighthouse/lingoswap/match/service/MatchService.java +++ b/src/main/java/com/lighthouse/lingoswap/match/service/MatchService.java @@ -1,5 +1,7 @@ package com.lighthouse.lingoswap.match.service; +import com.lighthouse.lingoswap.common.dto.SliceDto; +import com.lighthouse.lingoswap.match.entity.MatchedMember; import com.lighthouse.lingoswap.match.repository.MatchedMemberQueryRepository; import com.lighthouse.lingoswap.match.repository.MatchedMemberRepository; import lombok.RequiredArgsConstructor; @@ -15,14 +17,18 @@ public class MatchService { private final MatchedMemberQueryRepository matchedMemberQueryRepository; private final MatchedMemberRepository matchedMemberRepository; + public SliceDto findFilteredMembers(Long memberId, Long nextId, int pageSize) { + return matchedMemberQueryRepository.findAllByFromMemberId(memberId, nextId, pageSize); + } + @Transactional - public void saveFilteredMembersWithPreferences( + public void saveMatchedMembersWithPreferences( Long memberId, List preferredCountryIds, List preferredLanguages, List preferredInterests) { - matchedMemberRepository.deletePreviousFilteredMember(memberId); - matchedMemberRepository.saveFilteredMembersWithPreferences( + matchedMemberRepository.deletePreviousMatchedMember(memberId); + matchedMemberRepository.saveMatchedMembersWithPreferences( memberId, preferredCountryIds, preferredLanguages, preferredInterests); } diff --git a/src/main/java/com/lighthouse/lingoswap/member/dto/MemberProfileResponse.java b/src/main/java/com/lighthouse/lingoswap/member/dto/MemberProfileResponse.java index 92db6e8..41ef64d 100644 --- a/src/main/java/com/lighthouse/lingoswap/member/dto/MemberProfileResponse.java +++ b/src/main/java/com/lighthouse/lingoswap/member/dto/MemberProfileResponse.java @@ -2,7 +2,7 @@ import java.util.List; -public record MemberProfileResponse(Long id, +public record MemberProfileResponse(String uuid, String profileImageUri, String name, int age, diff --git a/src/main/java/com/lighthouse/lingoswap/member/service/MemberManager.java b/src/main/java/com/lighthouse/lingoswap/member/service/MemberManager.java index 6160a43..7193dda 100644 --- a/src/main/java/com/lighthouse/lingoswap/member/service/MemberManager.java +++ b/src/main/java/com/lighthouse/lingoswap/member/service/MemberManager.java @@ -62,7 +62,7 @@ public ResponseDto read(final String uuid, Locale locale) Member member = memberService.findByUuidWithRegionAndUsedLanguage(uuid); Map> interestsMap = groupInterestsByCategory(preferredInterestsService.findAllByMemberIdWithInterestsAndCategory(member.getId())); List usedLanguages = member.getUsedLanguages(); - return ResponseDto.success(new MemberProfileResponse(member.getId(), distributionService.generateUri(profileKeyPrefix + member.getProfileImageUri()), member.getName(), member.calculateAge(), member.getDescription(), member.getRegion().getCode(), + return ResponseDto.success(new MemberProfileResponse(member.getAuthDetails().getUuid(), distributionService.generateUri(profileKeyPrefix + member.getProfileImageUri()), member.getName(), member.calculateAge(), member.getDescription(), member.getRegion().getCode(), preferredCountryService.findAllByMemberIdWithCountry(member.getId()).stream().map(c -> new CountryFormResponseUnit(c.getCountry().getCode(), messageSource.getMessage(c.getCountry().getCode(), null, locale))).toList(), usedLanguages.stream().map(MemberUsedLanguage::from).toList(), interestsMap.entrySet().stream().map(entry -> MemberPreferredInterests.of(new CategoryDto(entry.getKey(), messageSource.getMessage(entry.getKey(), null, locale)), diff --git a/src/main/java/com/lighthouse/lingoswap/question/api/QuestionController.java b/src/main/java/com/lighthouse/lingoswap/question/api/QuestionController.java index 733e5f5..a1c1a9f 100644 --- a/src/main/java/com/lighthouse/lingoswap/question/api/QuestionController.java +++ b/src/main/java/com/lighthouse/lingoswap/question/api/QuestionController.java @@ -44,9 +44,9 @@ public ResponseEntity> deleteLike(@PathVariable Long questio } @GetMapping(path = "/recommendation/{categoryId}") - public ResponseEntity getRecommendation(@PathVariable Long categoryId, - @RequestParam(required = false) final Long next, - @RequestParam(defaultValue = "10") final int pageSize) { + public ResponseEntity> getRecommendation(@PathVariable Long categoryId, + @RequestParam(required = false) final Long next, + @RequestParam(defaultValue = "10") final int pageSize) { return ResponseEntity.ok(questionManager.readRecommendation(categoryId, next, pageSize)); } } diff --git a/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionDeleteLikeRequest.java b/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionDeleteLikeRequest.java index d35eba9..edda393 100644 --- a/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionDeleteLikeRequest.java +++ b/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionDeleteLikeRequest.java @@ -1,5 +1,5 @@ package com.lighthouse.lingoswap.question.dto; -public record QuestionDeleteLikeRequest(String userId) { +public record QuestionDeleteLikeRequest(String uuid) { } diff --git a/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionDetail.java b/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionDetail.java index 1e45da3..724d5fa 100644 --- a/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionDetail.java +++ b/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionDetail.java @@ -3,10 +3,10 @@ import com.lighthouse.lingoswap.member.entity.Member; import com.lighthouse.lingoswap.question.entity.Question; -public record QuestionDetail(Long questionId, Long userId, String profileImageUri, String name, String region, +public record QuestionDetail(Long questionId, String uuid, String profileImageUri, String name, String region, String contents, Integer likes, boolean clicked) { public static QuestionDetail of(Question question, Member member, boolean clicked) { - return new QuestionDetail(question.getId(), member.getId(), member.getProfileImageUri(), member.getName(), member.getRegion().getCode(), question.getContents(), question.getLikes(), clicked); + return new QuestionDetail(question.getId(), member.getAuthDetails().getUuid(), member.getProfileImageUri(), member.getName(), member.getRegion().getCode(), question.getContents(), question.getLikes(), clicked); } } diff --git a/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionUpdateLikeRequest.java b/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionUpdateLikeRequest.java index aad504d..90546fa 100644 --- a/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionUpdateLikeRequest.java +++ b/src/main/java/com/lighthouse/lingoswap/question/dto/QuestionUpdateLikeRequest.java @@ -1,5 +1,5 @@ package com.lighthouse.lingoswap.question.dto; -public record QuestionUpdateLikeRequest(String userId) { +public record QuestionUpdateLikeRequest(String uuid) { } diff --git a/src/main/java/com/lighthouse/lingoswap/question/service/QuestionManager.java b/src/main/java/com/lighthouse/lingoswap/question/service/QuestionManager.java index 93c454f..624b7b0 100644 --- a/src/main/java/com/lighthouse/lingoswap/question/service/QuestionManager.java +++ b/src/main/java/com/lighthouse/lingoswap/question/service/QuestionManager.java @@ -46,7 +46,7 @@ public ResponseDto read(final String uuid, final Long cate @Transactional public ResponseDto updateLike(final Long questionId, final QuestionUpdateLikeRequest questionUpdateLikeRequest) { Question question = questionService.findById(questionId); - Member member = memberService.findByUuid(questionUpdateLikeRequest.userId()); + Member member = memberService.findByUuid(questionUpdateLikeRequest.uuid()); LikeMember likeMember = LikeMember.of(member, question); likeMemberService.save(likeMember); @@ -59,7 +59,7 @@ public ResponseDto updateLike(final Long questionId, final QuestionUpdat @Transactional public ResponseDto deleteLike(final Long questionId, final QuestionDeleteLikeRequest questionDeleteLikeRequest) { Question question = questionService.findById(questionId); - Member member = memberService.findByUuid(questionDeleteLikeRequest.userId()); + Member member = memberService.findByUuid(questionDeleteLikeRequest.uuid()); likeMemberService.deleteByQuestionAndMember(question, member); question.subtractOneLike(); @@ -67,11 +67,11 @@ public ResponseDto deleteLike(final Long questionId, final QuestionDelet return ResponseDto.success(null); } - public QuestionRecommendationListResponse readRecommendation(Long categoryId, Long nextId, int pageSize) { + public ResponseDto readRecommendation(Long categoryId, Long nextId, int pageSize) { SliceDto questionRecommendations = questionService.searchRecommendation(categoryId, nextId, pageSize); List results = new ArrayList<>(); questionRecommendations.content().stream().forEach(q -> results.add(q.getContents())); - return new QuestionRecommendationListResponse(questionRecommendations.nextId(), results); + return ResponseDto.success(new QuestionRecommendationListResponse(questionRecommendations.nextId(), results)); } } From 73e270224463ebce3624ffc45c86f038393d119c Mon Sep 17 00:00:00 2001 From: HyeonJun An Date: Fri, 22 Sep 2023 02:40:53 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[LH-195]=20batch=20scheduler=20=EB=AF=B8?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20(#43)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/lighthouse/lingoswap/LingoSwapApplication.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/lighthouse/lingoswap/LingoSwapApplication.java b/src/main/java/com/lighthouse/lingoswap/LingoSwapApplication.java index 144f12f..98984ff 100644 --- a/src/main/java/com/lighthouse/lingoswap/LingoSwapApplication.java +++ b/src/main/java/com/lighthouse/lingoswap/LingoSwapApplication.java @@ -3,10 +3,8 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication -@EnableScheduling @EnableJpaAuditing public class LingoSwapApplication {