Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@
import com.example.solidconnection.common.resolver.AuthorizedUser;
import com.example.solidconnection.university.dto.IsLikeResponse;
import com.example.solidconnection.university.dto.UnivApplyInfoDetailResponse;
import com.example.solidconnection.university.dto.UnivApplyInfoFilterSearchRequest;
import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponse;
import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponses;
import com.example.solidconnection.university.dto.UnivApplyInfoRecommendsResponse;
import com.example.solidconnection.university.service.LikedUnivApplyInfoService;
import com.example.solidconnection.university.service.UnivApplyInfoQueryService;
import com.example.solidconnection.university.service.UnivApplyInfoRecommendService;
import jakarta.validation.Valid;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -87,14 +84,6 @@ public ResponseEntity<UnivApplyInfoDetailResponse> getUnivApplyInfoDetails(
return ResponseEntity.ok(univApplyInfoDetailResponse);
}

@GetMapping("/search/filter")
public ResponseEntity<UnivApplyInfoPreviewResponses> searchUnivApplyInfoByFilter(
@Valid @ModelAttribute UnivApplyInfoFilterSearchRequest request
) {
UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request);
return ResponseEntity.ok(response);
}

@GetMapping("/search/text")
public ResponseEntity<UnivApplyInfoPreviewResponses> searchUnivApplyInfoByText(
@RequestParam(required = false) String value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
Expand All @@ -36,8 +37,9 @@ public class UnivApplyInfo extends BaseEntity {
@Column(nullable = false, name = "term_id")
private long termId;

@Column(name = "home_university_id")
private Long homeUniversityId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "home_university_id")
private HomeUniversity homeUniversity;

@Column(nullable = false, length = 100)
private String koreanName;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,30 @@ public record UnivApplyInfoPreviewResponse(
long id,
String term,
String koreanName,
String homeUniversityName,
String region,
String country,
String logoImageUrl,
String backgroundImageUrl,
int studentCapacity,
List<LanguageRequirementResponse> languageRequirements) {

public static UnivApplyInfoPreviewResponse from(UnivApplyInfo univApplyInfo, String termName) {
public static UnivApplyInfoPreviewResponse of(UnivApplyInfo univApplyInfo, String termName) {
List<LanguageRequirementResponse> languageRequirementResponses = new ArrayList<>(
univApplyInfo.getLanguageRequirements().stream()
.map(LanguageRequirementResponse::from)
.toList());
Collections.sort(languageRequirementResponses);

String homeUniversityName = univApplyInfo.getHomeUniversity() != null
? univApplyInfo.getHomeUniversity().getName()
: null;

return new UnivApplyInfoPreviewResponse(
univApplyInfo.getId(),
termName,
univApplyInfo.getKoreanName(),
homeUniversityName,
univApplyInfo.getUniversity().getRegion().getKoreanName(),
univApplyInfo.getUniversity().getCountry().getKoreanName(),
univApplyInfo.getUniversity().getLogoImageUrl(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.solidconnection.university.repository;

import com.example.solidconnection.university.domain.HomeUniversity;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;

public interface HomeUniversityRepository extends JpaRepository<HomeUniversity, Long> {

List<HomeUniversity> findAllByIdIn(List<Long> ids);

Optional<HomeUniversity> findByName(String name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@ public interface LikedUnivApplyInfoRepository extends JpaRepository<LikedUnivApp
Optional<LikedUnivApplyInfo> findBySiteUserIdAndUnivApplyInfoId(long siteUserId, long univApplyInfoId);

@Query("""
SELECT u
SELECT DISTINCT u
FROM UnivApplyInfo u
LEFT JOIN FETCH u.languageRequirements lr
LEFT JOIN FETCH u.homeUniversity hu
LEFT JOIN FETCH u.university univ
LEFT JOIN FETCH univ.country c
LEFT JOIN FETCH univ.region r
JOIN LikedUnivApplyInfo l ON u.id = l.univApplyInfoId
WHERE l.siteUserId = :siteUserId
""")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public interface UnivApplyInfoRepository extends JpaRepository<UnivApplyInfo, Lo
SELECT DISTINCT uai
FROM UnivApplyInfo uai
LEFT JOIN FETCH uai.languageRequirements lr
LEFT JOIN FETCH uai.homeUniversity hu
JOIN FETCH uai.university u
LEFT JOIN FETCH u.country c
LEFT JOIN FETCH u.region r
Expand All @@ -40,6 +41,7 @@ OR r.code IN (
SELECT uai
FROM UnivApplyInfo uai
LEFT JOIN FETCH uai.languageRequirements lr
LEFT JOIN FETCH uai.homeUniversity hu
LEFT JOIN FETCH uai.university u
LEFT JOIN FETCH u.country c
LEFT JOIN FETCH u.region r
Expand All @@ -57,6 +59,7 @@ default UnivApplyInfo getUnivApplyInfoById(Long id) {
SELECT DISTINCT uai
FROM UnivApplyInfo uai
LEFT JOIN FETCH uai.languageRequirements lr
LEFT JOIN FETCH uai.homeUniversity hu
LEFT JOIN FETCH uai.university u
LEFT JOIN FETCH u.country c
LEFT JOIN FETCH u.region r
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package com.example.solidconnection.university.repository.custom;

import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.UnivApplyInfo;
import java.util.List;

public interface UnivApplyInfoFilterRepository {

List<UnivApplyInfo> findAllByRegionCodeAndKeywordsAndTermId(String regionCode, List<String> keywords, Long term);

List<UnivApplyInfo> findAllByFilter(LanguageTestType testType, String testScore, Long termId, List<String> countryKoreanNames);

List<UnivApplyInfo> findAllByText(String text, Long termId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import com.example.solidconnection.location.country.domain.QCountry;
import com.example.solidconnection.location.region.domain.QRegion;
import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.QHomeUniversity;
import com.example.solidconnection.university.domain.QHostUniversity;
import com.example.solidconnection.university.domain.QLanguageRequirement;
import com.example.solidconnection.university.domain.QUnivApplyInfo;
import com.example.solidconnection.university.domain.QHostUniversity;
import com.example.solidconnection.university.domain.UnivApplyInfo;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression;
Expand Down Expand Up @@ -34,13 +34,15 @@ public UnivApplyInfoFilterRepositoryImpl(EntityManager em) {
public List<UnivApplyInfo> findAllByRegionCodeAndKeywordsAndTermId(String regionCode, List<String> keywords, Long termId) {
QUnivApplyInfo univApplyInfo = QUnivApplyInfo.univApplyInfo;
QHostUniversity university = QHostUniversity.hostUniversity;
QHomeUniversity homeUniversity = QHomeUniversity.homeUniversity;
QCountry country = QCountry.country;
QLanguageRequirement languageRequirement = QLanguageRequirement.languageRequirement;

return queryFactory
.selectFrom(univApplyInfo)
.join(univApplyInfo.university, university).fetchJoin()
.join(university.country, country).fetchJoin()
.leftJoin(univApplyInfo.homeUniversity, homeUniversity).fetchJoin()
.leftJoin(univApplyInfo.languageRequirements, languageRequirement).fetchJoin()
.where(
regionCodeEq(country, regionCode)
Expand Down Expand Up @@ -74,79 +76,18 @@ private BooleanExpression createKeywordCondition(StringPath namePath, List<Strin
.orElse(Expressions.FALSE);
}

@Override
public List<UnivApplyInfo> findAllByFilter(
LanguageTestType testType, String testScore, Long termId, List<String> countryCodes
) {
QHostUniversity university = QHostUniversity.hostUniversity;
QUnivApplyInfo univApplyInfo = QUnivApplyInfo.univApplyInfo;
QCountry country = QCountry.country;
QLanguageRequirement languageRequirement = QLanguageRequirement.languageRequirement;

List<UnivApplyInfo> filteredUnivApplyInfo = queryFactory.selectFrom(univApplyInfo)
.join(univApplyInfo.university, university)
.join(university.country, country)
.join(univApplyInfo.languageRequirements, languageRequirement)
.fetchJoin()
.where(
languageTestTypeEq(languageRequirement, testType),
termIdEq(univApplyInfo, termId),
countryCodesIn(country, countryCodes)
)
.distinct()
.fetch();

if (testScore == null || testScore.isBlank()) {
return filteredUnivApplyInfo;
}

/*
* 시험 유형에 따라 성적 비교 방식이 다르다.
* 입력된 점수가 대학에서 요구하는 최소 점수보다 높은지를 '쿼리로' 비교하기엔 쿼리가 지나치게 복잡해진다.
* 따라서 이 부분만 자바 코드로 필터링한다.
* */
return filteredUnivApplyInfo.stream()
.filter(uai -> isGivenScoreOverMinPassScore(uai, testType, testScore))
.toList();
}

private BooleanExpression languageTestTypeEq(
QLanguageRequirement languageRequirement, LanguageTestType givenTestType
) {
if (givenTestType == null) {
return null;
}
return languageRequirement.languageTestType.eq(givenTestType);
}

private BooleanExpression termIdEq(QUnivApplyInfo univApplyInfo, Long givenTermId) {
if (givenTermId == null) {
return null;
}
return univApplyInfo.termId.eq(givenTermId);
}

private BooleanExpression countryCodesIn(QCountry country, List<String> givenCountryCodes) {
if (givenCountryCodes == null || givenCountryCodes.isEmpty()) {
return null;
}
return country.code.in(givenCountryCodes);
}

private boolean isGivenScoreOverMinPassScore(
UnivApplyInfo univApplyInfo, LanguageTestType givenTestType, String givenTestScore
) {
return univApplyInfo.getLanguageRequirements().stream()
.filter(languageRequirement -> languageRequirement.getLanguageTestType().equals(givenTestType))
.findFirst()
.map(requirement -> givenTestType.compare(givenTestScore, requirement.getMinScore()))
.orElse(-1) >= 0;
}

@Override
public List<UnivApplyInfo> findAllByText(String text, Long termId) {
QUnivApplyInfo univApplyInfo = QUnivApplyInfo.univApplyInfo;
QHostUniversity university = QHostUniversity.hostUniversity;
QHomeUniversity homeUniversity = QHomeUniversity.homeUniversity;
QLanguageRequirement languageRequirement = QLanguageRequirement.languageRequirement;
QCountry country = QCountry.country;
QRegion region = QRegion.region;
Expand All @@ -155,6 +96,7 @@ public List<UnivApplyInfo> findAllByText(String text, Long termId) {
.join(univApplyInfo.university, university).fetchJoin()
.join(university.country, country).fetchJoin()
.join(region).on(country.regionCode.eq(region.code))
.leftJoin(univApplyInfo.homeUniversity, homeUniversity).fetchJoin()
.leftJoin(univApplyInfo.languageRequirements, languageRequirement).fetchJoin()
.where(termIdEq(univApplyInfo, termId));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand Down Expand Up @@ -46,7 +45,7 @@ public List<UnivApplyInfoPreviewResponse> getLikedUnivApplyInfos(long siteUserId
return univApplyInfos.stream()
.map(univApplyInfo -> {
String termName = termMap.getOrDefault(univApplyInfo.getTermId(), "Unknown");
return UnivApplyInfoPreviewResponse.from(univApplyInfo, termName);
return UnivApplyInfoPreviewResponse.of(univApplyInfo, termName);
})
.toList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.term.domain.Term;
import com.example.solidconnection.term.repository.TermRepository;
import com.example.solidconnection.university.domain.UnivApplyInfo;
import com.example.solidconnection.university.domain.HostUniversity;
import com.example.solidconnection.university.domain.UnivApplyInfo;
import com.example.solidconnection.university.dto.UnivApplyInfoDetailResponse;
import com.example.solidconnection.university.dto.UnivApplyInfoFilterSearchRequest;
import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponse;
import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponses;
import com.example.solidconnection.university.repository.UnivApplyInfoRepository;
Expand Down Expand Up @@ -42,34 +41,16 @@ public UnivApplyInfoDetailResponse getUnivApplyInfoDetail(Long univApplyInfoId)
return UnivApplyInfoDetailResponse.of(university, univApplyInfo, term.getName());
}

@Transactional(readOnly = true)
public UnivApplyInfoPreviewResponses searchUnivApplyInfoByFilter(UnivApplyInfoFilterSearchRequest request) {
Term term = termRepository.findByIsCurrentTrue()
.orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND));

List<UnivApplyInfoPreviewResponse> responses = univApplyInfoRepository
.findAllByFilter(request.languageTestType(), request.testScore(), term.getId(), request.countryCode())
.stream()
.map(univApplyInfo -> UnivApplyInfoPreviewResponse.from(
univApplyInfo,
term.getName()
))
.toList();
return new UnivApplyInfoPreviewResponses(responses);
}

@Transactional(readOnly = true)
@ThunderingHerdCaching(key = "univApplyInfoTextSearch:{0}", cacheManager = "customCacheManager", ttlSec = 86400)
public UnivApplyInfoPreviewResponses searchUnivApplyInfoByText(String text) {
Term term = termRepository.findByIsCurrentTrue()
.orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND));

List<UnivApplyInfoPreviewResponse> responses = univApplyInfoRepository.findAllByText(text, term.getId())
.stream()
.map(univApplyInfo -> UnivApplyInfoPreviewResponse.from(
univApplyInfo,
term.getName()
))
List<UnivApplyInfo> univApplyInfos = univApplyInfoRepository.findAllByText(text, term.getId());

List<UnivApplyInfoPreviewResponse> responses = univApplyInfos.stream()
.map(univApplyInfo -> UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName()))
.toList();
return new UnivApplyInfoPreviewResponses(responses);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,8 @@ public UnivApplyInfoRecommendsResponse getPersonalRecommends(long siteUserId) {
}

return new UnivApplyInfoRecommendsResponse(trimmedRecommends.stream()
.map(univApplyInfo -> UnivApplyInfoPreviewResponse.from(
univApplyInfo,
term.getName()
))
.toList());
.map(univApplyInfo -> UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName()))
.toList());
}

private List<UnivApplyInfo> getGeneralRecommendsExcludingSelected(List<UnivApplyInfo> alreadyPicked) {
Expand All @@ -76,11 +73,9 @@ public UnivApplyInfoRecommendsResponse getGeneralRecommends() {
.orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND));

List<UnivApplyInfo> generalRecommends = new ArrayList<>(generalUnivApplyInfoRecommendService.getGeneralRecommends());

return new UnivApplyInfoRecommendsResponse(generalRecommends.stream()
.map(univApplyInfo -> UnivApplyInfoPreviewResponse.from(
univApplyInfo,
term.getName()
))
.toList());
.map(univApplyInfo -> UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName()))
.toList());
}
}
Loading
Loading