From 5a11bc43de2791d9e1534926821ddfd0567289a2 Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sat, 24 Jan 2026 23:26:40 +0900 Subject: [PATCH 01/14] =?UTF-8?q?refactor:=20home=5Funiversity=EC=99=80=20?= =?UTF-8?q?university=5Finfo=5Ffor=5Fapply=EA=B0=80=20FK=20=EA=B4=80?= =?UTF-8?q?=EA=B3=84=EB=A5=BC=20=EA=B0=80=EC=A7=80=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../university/domain/HostUniversity.java | 5 ----- .../university/domain/UnivApplyInfo.java | 3 +++ ...3__move_home_university_fk_to_univ_apply_info.sql | 12 ++++++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/db/migration/V43__move_home_university_fk_to_univ_apply_info.sql diff --git a/src/main/java/com/example/solidconnection/university/domain/HostUniversity.java b/src/main/java/com/example/solidconnection/university/domain/HostUniversity.java index e36c2caa..3d817b45 100644 --- a/src/main/java/com/example/solidconnection/university/domain/HostUniversity.java +++ b/src/main/java/com/example/solidconnection/university/domain/HostUniversity.java @@ -8,9 +8,7 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import jakarta.persistence.FetchType; import jakarta.persistence.ManyToOne; -import jakarta.persistence.Table; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @@ -58,7 +56,4 @@ public class HostUniversity extends BaseEntity { @ManyToOne private Region region; - - @ManyToOne(fetch = FetchType.LAZY) - private HomeUniversity homeUniversity; } diff --git a/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java b/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java index e4c089c6..a727a74e 100644 --- a/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java +++ b/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java @@ -36,6 +36,9 @@ public class UnivApplyInfo extends BaseEntity { @Column(nullable = false, name = "term_id") private long termId; + @Column(name = "home_university_id") + private Long homeUniversityId; + @Column(nullable = false, length = 100) private String koreanName; diff --git a/src/main/resources/db/migration/V43__move_home_university_fk_to_univ_apply_info.sql b/src/main/resources/db/migration/V43__move_home_university_fk_to_univ_apply_info.sql new file mode 100644 index 00000000..36ba62a9 --- /dev/null +++ b/src/main/resources/db/migration/V43__move_home_university_fk_to_univ_apply_info.sql @@ -0,0 +1,12 @@ +ALTER TABLE host_university + DROP FOREIGN KEY fk_host_university_home_university; + +ALTER TABLE host_university + DROP COLUMN home_university_id; + +ALTER TABLE university_info_for_apply + ADD COLUMN home_university_id BIGINT NULL; + +ALTER TABLE university_info_for_apply + ADD CONSTRAINT fk_university_info_for_apply_home_university + FOREIGN KEY (home_university_id) REFERENCES home_university (id) ON DELETE NO ACTION; From ff30af83ff440ae185b0cc28a8852269896bf426 Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sat, 24 Jan 2026 23:29:17 +0900 Subject: [PATCH 02/14] =?UTF-8?q?chore:=20FK=20=EB=B3=80=EA=B2=BD=EC=97=90?= =?UTF-8?q?=20=EB=94=B0=EB=A5=B8=20=EB=AA=A9=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/data.sql | 38 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 0f46eba1..ce4fca9c 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -50,100 +50,100 @@ VALUES ('test@test.email', 'yonso', 'https://github.com/nayonsoso.png', INSERT INTO home_university (id, name) VALUES (1, '인하대학교'); -INSERT INTO host_university(id, home_university_id, country_code, region_code, english_name, format_name, korean_name, +INSERT INTO host_university(id, country_code, region_code, english_name, format_name, korean_name, accommodation_url, english_course_url, homepage_url, details_for_local, logo_image_url, background_image_url) -VALUES (1, 1, 'US', 'AMERICAS', 'University of Guam', 'university_of_guam', '괌대학', +VALUES (1, 'US', 'AMERICAS', 'University of Guam', 'university_of_guam', '괌대학', 'https://www.uog.edu/life-at-uog/residence-halls/', 'https://www.uog.edu/admissions/course-schedule', 'https://www.uog.edu/admissions/international-students', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_guam/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_guam/1.png'), - (2, 1, 'US', 'AMERICAS', 'University of Nevada, Las Vegas', 'university_of_nevada_las_vegas', '네바다주립대학 라스베이거스', + (2, 'US', 'AMERICAS', 'University of Nevada, Las Vegas', 'university_of_nevada_las_vegas', '네바다주립대학 라스베이거스', 'https://www.unlv.edu/housing', 'https://www.unlv.edu/engineering/academic-programs', 'https://www.unlv.edu/engineering/eip', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_nevada_las_vegas/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_nevada_las_vegas/1.png'), - (3, 1, 'CA', 'AMERICAS', 'Memorial University of Newfoundland St. John''s', + (3, 'CA', 'AMERICAS', 'Memorial University of Newfoundland St. John''s', 'memorial_university_of_newfoundland_st_johns', '메모리얼 대학 세인트존스', 'https://www.mun.ca/residences/', 'https://www.mun.ca/regoff/registration-and-final-exams/course-offerings/', 'https://mun.ca/goabroad/visiting-students-inbound/', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/memorial_university_of_newfoundland_st_johns/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/memorial_university_of_newfoundland_st_johns/1.png'), - (4, 1, 'AU', 'AMERICAS', 'University of Southern Queensland', 'university_of_southern_queensland', '서던퀸스랜드대학', + (4, 'AU', 'AMERICAS', 'University of Southern Queensland', 'university_of_southern_queensland', '서던퀸스랜드대학', 'https://www.unisq.edu.au/current-students/support/accommodation', 'https://www.unisq.edu.au/course/specification/current/', 'https://www.unisq.edu.au/international/partnerships/study-abroad-exchange', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_southern_queensland/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_southern_queensland/1.png'), - (5, 1, 'AU', 'AMERICAS', 'University of Sydney', 'university_of_sydney', '시드니대학', + (5, 'AU', 'AMERICAS', 'University of Sydney', 'university_of_sydney', '시드니대학', 'https://www.sydney.edu.au/study/accommodation.html', 'www.sydney.edu.au/sydney-abroad-units', 'https://www.sydney.edu.au/', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_sydney/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_sydney/1.png'), - (6, 1, 'AU', 'AMERICAS', 'Curtin University', 'curtin_university', '커틴대학', + (6, 'AU', 'AMERICAS', 'Curtin University', 'curtin_university', '커틴대학', 'https://www.curtin.edu.au/study/campus-life/accommodation/#perth', 'https://handbook.curtin.edu.au/', 'https://www.curtin.edu.au/', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/curtin_university/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/curtin_university/1.png'), - (7, 1, 'DK', 'EUROPE', 'University of Southern Denmark', 'university_of_southern_denmark', '서던덴마크대학교', + (7, 'DK', 'EUROPE', 'University of Southern Denmark', 'university_of_southern_denmark', '서던덴마크대학교', 'https://www.sdu.dk/en/uddannelse/information_for_international_students/studenthousing', 'https://www.sdu.dk/en/uddannelse/exchange_programmes', 'https://www.sdu.dk/en', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_southern_denmark/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_southern_denmark/1.png'), - (8, 1, 'DK', 'EUROPE', 'IT University of Copenhagen', 'it_university_of_copenhagen', '코펜하겐 IT대학', + (8, 'DK', 'EUROPE', 'IT University of Copenhagen', 'it_university_of_copenhagen', '코펜하겐 IT대학', 'https://en.itu.dk/Programmes/Student-Life/Practical-information-for-international-students', 'https://en.itu.dk/Programmes/Exchange-students/Become-an-exchange-student-at-ITU', 'https://en.itu.dk/programmes/exchange-students/become-an-exchange-student-at-itu', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/it_university_of_copenhagen/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/it_university_of_copenhagen/1.png'), - (9, 1, 'DE', 'EUROPE', 'Neu-Ulm University of Applied Sciences', 'neu-ulm_university_of_applied_sciences', + (9, 'DE', 'EUROPE', 'Neu-Ulm University of Applied Sciences', 'neu-ulm_university_of_applied_sciences', '노이울름 대학', 'https://www.hnu.de/fileadmin/user_upload/5_Internationales/International_Incomings/Bewerbung/Housing_Broschure.pdf', 'https://www.hnu.de/en/international/international-exchange-students/courses-taught-in-english', 'https://www.hnu.de/en/international', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/neu-ulm_university_of_applied_sciences/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/neu-ulm_university_of_applied_sciences/1.png'), - (10, 1, 'GB', 'EUROPE', 'University of Hull', 'university_of_hull', '헐대학', + (10, 'GB', 'EUROPE', 'University of Hull', 'university_of_hull', '헐대학', 'https://www.hull.ac.uk/Choose-Hull/Student-life/Accommodation/accommodation.aspx', 'https://universityofhull.app.box.com/s/mpvulz3yz0uijdt68rybce19nek0d8eh', 'https://www.hull.ac.uk/choose-hull/study-at-hull/need-to-know/key-dates', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_hull/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_hull/1.png'), - (11, 1, 'AT', 'EUROPE', 'University of Graz', 'university_of_graz', '그라츠 대학', + (11, 'AT', 'EUROPE', 'University of Graz', 'university_of_graz', '그라츠 대학', 'https://orientation.uni-graz.at/de/planning-the-arrival/accommodation/', 'https://static.uni-graz.at/fileadmin/veranstaltungen/orientation/documents/incstud_application-courses.pdf', 'https://www.uni-graz.at/en/', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_graz/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_graz/1.png'), - (12, 1, 'AT', 'EUROPE', 'Graz University of Technology', 'graz_university_of_technology', '그라츠공과대학', + (12, 'AT', 'EUROPE', 'Graz University of Technology', 'graz_university_of_technology', '그라츠공과대학', 'https://www.tugraz.at/en/studying-and-teaching/studying-internationally/incoming-students-exchange-at-tu-graz/your-stay-at-tu-graz/preparation#c75033', 'https://tugraz.at/go/search-courses', 'https://www.tugraz.at/en/home', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/graz_university_of_technology/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/graz_university_of_technology/1.png'), - (13, 1, 'AT', 'EUROPE', 'Catholic Private University Linz', 'catholic_private_university_linz', '린츠 카톨릭 대학교', NULL, + (13, 'AT', 'EUROPE', 'Catholic Private University Linz', 'catholic_private_university_linz', '린츠 카톨릭 대학교', NULL, 'https://ku-linz.at/en/ku_international/incomings/kulis', 'https://ku-linz.at/en', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/catholic_private_university_linz/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/catholic_private_university_linz/1.png'), - (14, 1, 'AT', 'EUROPE', 'University of Applied Sciences Technikum Wien', + (14, 'AT', 'EUROPE', 'University of Applied Sciences Technikum Wien', 'university_of_applied_sciences_technikum_wien', '빈 공과대학교', NULL, 'https://www.technikum-wien.at/en/international/student-mobility/', 'https://www.technikum-wien.at/international/studierendenmobilitaet-2/', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_applied_sciences_technikum_wien/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_applied_sciences_technikum_wien/1.png'), - (15, 1, 'FR', 'EUROPE', 'IPSA', 'ipsa', 'IPSA', 'https://www.ipsa.fr/en/student-life/pratical-information/', NULL, + (15, 'FR', 'EUROPE', 'IPSA', 'ipsa', 'IPSA', 'https://www.ipsa.fr/en/student-life/pratical-information/', NULL, 'https://www.ipsa.fr/en/engineering-school/aeronautical-space', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/ipsa/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/ipsa/1.png'), - (16, 1, 'JP', 'ASIA', 'Meiji University', 'meiji_university', '메이지대학', + (16, 'JP', 'ASIA', 'Meiji University', 'meiji_university', '메이지대학', 'https://www.meiji.ac.jp/cip/english/admissions/co7mm90000000461-att/co7mm900000004fa.pdf', NULL, 'https://www.meiji.ac.jp/cip/english/admissions/co7mm90000000461-att/co7mm900000004fa.pdf', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/meiji_university/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/meiji_university/1.png'), - (17, 1, 'JP', 'ASIA', 'BAIKA Women''s University', 'baika_womens_university', '바이카여자대학', + (17, 'JP', 'ASIA', 'BAIKA Women''s University', 'baika_womens_university', '바이카여자대학', 'https://dormy-ac.com/page/baika/', NULL, 'https://www.baika.ac.jp/english/', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/baika_womens_university/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/baika_womens_university/1.png'), - (18, 1, 'JP', 'ASIA', 'Bunkyo Gakuin University', 'bunkyo_gakuin_university', '분쿄가쿠인대학', NULL, NULL, + (18, 'JP', 'ASIA', 'Bunkyo Gakuin University', 'bunkyo_gakuin_university', '분쿄가쿠인대학', NULL, NULL, 'https://www.bgu.ac.jp/', NULL, 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/bunkyo_gakuin_university/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/bunkyo_gakuin_university/1.png'); From 0c106e708641962ef272d5b734cefabaac2f2c5d Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 13:51:10 +0900 Subject: [PATCH 03/14] =?UTF-8?q?refactor:=20=ED=95=84=ED=84=B0=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EC=97=94=EB=93=9C=ED=8F=AC=EC=9D=B8?= =?UTF-8?q?=ED=8A=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/UnivApplyInfoController.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/java/com/example/solidconnection/university/controller/UnivApplyInfoController.java b/src/main/java/com/example/solidconnection/university/controller/UnivApplyInfoController.java index 0a258ef1..c6ea2a2a 100644 --- a/src/main/java/com/example/solidconnection/university/controller/UnivApplyInfoController.java +++ b/src/main/java/com/example/solidconnection/university/controller/UnivApplyInfoController.java @@ -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; @@ -87,14 +84,6 @@ public ResponseEntity getUnivApplyInfoDetails( return ResponseEntity.ok(univApplyInfoDetailResponse); } - @GetMapping("/search/filter") - public ResponseEntity searchUnivApplyInfoByFilter( - @Valid @ModelAttribute UnivApplyInfoFilterSearchRequest request - ) { - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request); - return ResponseEntity.ok(response); - } - @GetMapping("/search/text") public ResponseEntity searchUnivApplyInfoByText( @RequestParam(required = false) String value From 0be2c030f178895eefc757e3ed097168de2de63c Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 13:51:41 +0900 Subject: [PATCH 04/14] =?UTF-8?q?refactor:=20=ED=95=84=ED=84=B0=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EA=B4=80=EB=A0=A8=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/UnivApplyInfoQueryService.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java index b8aa878f..470a8157 100644 --- a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java +++ b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java @@ -10,7 +10,6 @@ import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.domain.HostUniversity; 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; @@ -42,22 +41,6 @@ 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 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) { From 5ed339f25b89d962222e9d86682c0cafe37e01c3 Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 13:52:54 +0900 Subject: [PATCH 05/14] =?UTF-8?q?refactor:=20=ED=95=84=ED=84=B0=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EA=B4=80=EB=A0=A8=20=EB=A0=88=ED=8F=AC?= =?UTF-8?q?=EC=A7=80=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/UnivApplyInfoFilterRepository.java | 3 - .../UnivApplyInfoFilterRepositoryImpl.java | 63 ------------------- 2 files changed, 66 deletions(-) diff --git a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepository.java b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepository.java index 5e2a0b90..31dfe355 100644 --- a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepository.java +++ b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepository.java @@ -1,6 +1,5 @@ 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; @@ -8,7 +7,5 @@ public interface UnivApplyInfoFilterRepository { List findAllByRegionCodeAndKeywordsAndTermId(String regionCode, List keywords, Long term); - List findAllByFilter(LanguageTestType testType, String testScore, Long termId, List countryKoreanNames); - List findAllByText(String text, Long termId); } diff --git a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java index e15a56d0..6347013a 100644 --- a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java +++ b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java @@ -2,7 +2,6 @@ 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.QLanguageRequirement; import com.example.solidconnection.university.domain.QUnivApplyInfo; import com.example.solidconnection.university.domain.QHostUniversity; @@ -74,51 +73,6 @@ private BooleanExpression createKeywordCondition(StringPath namePath, List findAllByFilter( - LanguageTestType testType, String testScore, Long termId, List countryCodes - ) { - QHostUniversity university = QHostUniversity.hostUniversity; - QUnivApplyInfo univApplyInfo = QUnivApplyInfo.univApplyInfo; - QCountry country = QCountry.country; - QLanguageRequirement languageRequirement = QLanguageRequirement.languageRequirement; - - List 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; @@ -126,23 +80,6 @@ private BooleanExpression termIdEq(QUnivApplyInfo univApplyInfo, Long givenTermI return univApplyInfo.termId.eq(givenTermId); } - private BooleanExpression countryCodesIn(QCountry country, List 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 findAllByText(String text, Long termId) { QUnivApplyInfo univApplyInfo = QUnivApplyInfo.univApplyInfo; From c599b1d93395a84f32cb95d901be36ba81fa2f20 Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 13:53:12 +0900 Subject: [PATCH 06/14] =?UTF-8?q?refactor:=20=ED=95=84=ED=84=B0=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EA=B4=80=EB=A0=A8=20DTO=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/UnivApplyInfoFilterSearchRequest.java | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoFilterSearchRequest.java diff --git a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoFilterSearchRequest.java b/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoFilterSearchRequest.java deleted file mode 100644 index a4907931..00000000 --- a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoFilterSearchRequest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.solidconnection.university.dto; - -import com.example.solidconnection.university.domain.LanguageTestType; -import jakarta.validation.constraints.NotNull; -import java.util.List; - -public record UnivApplyInfoFilterSearchRequest( - - @NotNull(message = "어학 시험 종류를 선택해주세요.") - LanguageTestType languageTestType, - String testScore, - List countryCode -) { - -} From c4738a658cf8d3e1cc633418c66277d42131754e Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 14:09:04 +0900 Subject: [PATCH 07/14] =?UTF-8?q?test:=20=ED=95=84=ED=84=B0=20=EA=B2=80?= =?UTF-8?q?=EC=83=89=20=EA=B4=80=EB=A0=A8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UnivApplyInfoQueryServiceTest.java | 71 ------------------- 1 file changed, 71 deletions(-) diff --git a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java index cf8a0590..2d776012 100644 --- a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java @@ -1,11 +1,9 @@ package com.example.solidconnection.university.service; import static com.example.solidconnection.common.exception.ErrorCode.UNIV_APPLY_INFO_NOT_FOUND; -import static com.example.solidconnection.university.domain.LanguageTestType.TOEIC; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; -import static org.junit.jupiter.api.Assertions.assertAll; import static org.mockito.BDDMockito.then; import static org.mockito.Mockito.times; @@ -15,10 +13,8 @@ import com.example.solidconnection.term.fixture.TermFixture; 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.fixture.LanguageRequirementFixture; import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.List; @@ -42,9 +38,6 @@ class UnivApplyInfoQueryServiceTest { @Autowired private UnivApplyInfoFixture univApplyInfoFixture; - @Autowired - private LanguageRequirementFixture languageRequirementFixture; - @Autowired private TermFixture termFixture; @@ -98,70 +91,6 @@ class 대학_지원_정보_상세_조회 { } } - @Nested - class 대학_지원_정보_필터링_검색 { - - @Test - void 어학_시험_종류로_필터링한다() { - // given - UnivApplyInfoFilterSearchRequest request = new UnivApplyInfoFilterSearchRequest(TOEIC, null, null); - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); - languageRequirementFixture.토익_800(괌대학_A_지원_정보); - UnivApplyInfo 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(term.getId()); - languageRequirementFixture.토플_70(괌대학_B_지원_정보); - - // when - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request); - - // then - assertThat(response.univApplyInfoPreviews()) - .containsExactly(UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName())); - } - - @Test - void 어학_시험_점수가_기준치_이상인_곳을_필터링한다() { - // given - UnivApplyInfoFilterSearchRequest request = new UnivApplyInfoFilterSearchRequest(TOEIC, "800", null); - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); - languageRequirementFixture.토익_800(괌대학_A_지원_정보); - UnivApplyInfo 괌대학_B_지원_정보 = univApplyInfoFixture.괌대학_B_지원_정보(term.getId()); - languageRequirementFixture.토익_900(괌대학_B_지원_정보); - - // when - UnivApplyInfoPreviewResponses response = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request); - - // then - assertThat(response.univApplyInfoPreviews()) - .containsExactly(UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName())); - } - - @Test - void 국가_코드로_필터링한다() { - // given - UnivApplyInfoFilterSearchRequest request1 = new UnivApplyInfoFilterSearchRequest(TOEIC, null, List.of("US")); - UnivApplyInfoFilterSearchRequest request2 = new UnivApplyInfoFilterSearchRequest(TOEIC, null, List.of("US", "CA")); - UnivApplyInfo 괌대학_A_지원_정보 = univApplyInfoFixture.괌대학_A_지원_정보(term.getId()); - languageRequirementFixture.토익_800(괌대학_A_지원_정보); - UnivApplyInfo 메모리얼대학_세인트존스_A_지원_정보 = univApplyInfoFixture.메모리얼대학_세인트존스_A_지원_정보(term.getId()); - languageRequirementFixture.토익_800(메모리얼대학_세인트존스_A_지원_정보); - - // when - UnivApplyInfoPreviewResponses response1 = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request1); - UnivApplyInfoPreviewResponses response2 = univApplyInfoQueryService.searchUnivApplyInfoByFilter(request2); - - // then - assertAll( - () -> assertThat(response1.univApplyInfoPreviews()) - .containsExactly(UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName())), - () -> assertThat(response2.univApplyInfoPreviews()) - .containsExactlyInAnyOrder( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보, term.getName()) - ) - ); - } - } - @Nested class 대학_지원_정보_텍스트_검색 { From 398814c28e026dd328c00c9dcc1d079af849e93b Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 14:25:32 +0900 Subject: [PATCH 08/14] =?UTF-8?q?refactor:=20=EC=A7=80=EC=9B=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=99=20=EA=B4=80=EB=A0=A8=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=EC=97=90=20=ED=98=91=EC=A0=95=20=EB=8C=80=ED=95=99=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/UnivApplyInfoPreviewResponse.java | 8 +++- .../repository/HomeUniversityRepository.java | 10 +++++ .../service/LikedUnivApplyInfoService.java | 22 +++++++++- .../service/UnivApplyInfoQueryService.java | 35 ++++++++++++--- .../UnivApplyInfoRecommendService.java | 44 ++++++++++++++----- 5 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/example/solidconnection/university/repository/HomeUniversityRepository.java diff --git a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java b/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java index 37deee8f..d95dd120 100644 --- a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java +++ b/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java @@ -9,6 +9,7 @@ public record UnivApplyInfoPreviewResponse( long id, String term, String koreanName, + String homeUniversityName, String region, String country, String logoImageUrl, @@ -16,7 +17,11 @@ public record UnivApplyInfoPreviewResponse( int studentCapacity, List languageRequirements) { - public static UnivApplyInfoPreviewResponse from(UnivApplyInfo univApplyInfo, String termName) { + public static UnivApplyInfoPreviewResponse of( + UnivApplyInfo univApplyInfo, + String termName, + String homeUniversityName + ) { List languageRequirementResponses = new ArrayList<>( univApplyInfo.getLanguageRequirements().stream() .map(LanguageRequirementResponse::from) @@ -27,6 +32,7 @@ public static UnivApplyInfoPreviewResponse from(UnivApplyInfo univApplyInfo, Str univApplyInfo.getId(), termName, univApplyInfo.getKoreanName(), + homeUniversityName, univApplyInfo.getUniversity().getRegion().getKoreanName(), univApplyInfo.getUniversity().getCountry().getKoreanName(), univApplyInfo.getUniversity().getLogoImageUrl(), diff --git a/src/main/java/com/example/solidconnection/university/repository/HomeUniversityRepository.java b/src/main/java/com/example/solidconnection/university/repository/HomeUniversityRepository.java new file mode 100644 index 00000000..6ae63317 --- /dev/null +++ b/src/main/java/com/example/solidconnection/university/repository/HomeUniversityRepository.java @@ -0,0 +1,10 @@ +package com.example.solidconnection.university.repository; + +import com.example.solidconnection.university.domain.HomeUniversity; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface HomeUniversityRepository extends JpaRepository { + + List findAllByIdIn(List ids); +} diff --git a/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java b/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java index c353edaf..d1b8b611 100644 --- a/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java +++ b/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java @@ -6,19 +6,22 @@ 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.HomeUniversity; import com.example.solidconnection.university.domain.LikedUnivApplyInfo; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.dto.IsLikeResponse; import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponse; +import com.example.solidconnection.university.repository.HomeUniversityRepository; import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.function.Function; 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; @@ -27,6 +30,7 @@ public class LikedUnivApplyInfoService { private final UnivApplyInfoRepository univApplyInfoRepository; + private final HomeUniversityRepository homeUniversityRepository; private final LikedUnivApplyInfoRepository likedUnivApplyInfoRepository; private final TermRepository termRepository; @@ -42,15 +46,29 @@ public List getLikedUnivApplyInfos(long siteUserId Map termMap = termRepository.findAllById(termIds).stream() .collect(Collectors.toMap(Term::getId, Term::getName)); + Map homeUniversityMap = getHomeUniversityMap(univApplyInfos); return univApplyInfos.stream() .map(univApplyInfo -> { String termName = termMap.getOrDefault(univApplyInfo.getTermId(), "Unknown"); - return UnivApplyInfoPreviewResponse.from(univApplyInfo, termName); + HomeUniversity homeUniversity = homeUniversityMap.get(univApplyInfo.getHomeUniversityId()); + String homeUniversityName = homeUniversity != null ? homeUniversity.getName() : null; + return UnivApplyInfoPreviewResponse.of(univApplyInfo, termName, homeUniversityName); }) .toList(); } + private Map getHomeUniversityMap(List univApplyInfos) { + List homeUniversityIds = univApplyInfos.stream() + .map(UnivApplyInfo::getHomeUniversityId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + return homeUniversityRepository.findAllByIdIn(homeUniversityIds).stream() + .collect(Collectors.toMap(HomeUniversity::getId, Function.identity())); + } + /* * 대학교를 '좋아요' 한다. * */ diff --git a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java index 470a8157..6c2c614d 100644 --- a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java +++ b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java @@ -7,13 +7,19 @@ 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.HomeUniversity; 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.UnivApplyInfoPreviewResponse; import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponses; +import com.example.solidconnection.university.repository.HomeUniversityRepository; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -23,6 +29,7 @@ public class UnivApplyInfoQueryService { private final UnivApplyInfoRepository univApplyInfoRepository; + private final HomeUniversityRepository homeUniversityRepository; private final TermRepository termRepository; /* @@ -47,13 +54,27 @@ public UnivApplyInfoPreviewResponses searchUnivApplyInfoByText(String text) { Term term = termRepository.findByIsCurrentTrue() .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); - List responses = univApplyInfoRepository.findAllByText(text, term.getId()) - .stream() - .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( - univApplyInfo, - term.getName() - )) + List univApplyInfos = univApplyInfoRepository.findAllByText(text, term.getId()); + Map homeUniversityMap = getHomeUniversityMap(univApplyInfos); + + List responses = univApplyInfos.stream() + .map(univApplyInfo -> { + HomeUniversity homeUniversity = homeUniversityMap.get(univApplyInfo.getHomeUniversityId()); + String homeUniversityName = homeUniversity != null ? homeUniversity.getName() : null; + return UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName(), homeUniversityName); + }) .toList(); return new UnivApplyInfoPreviewResponses(responses); } + + private Map getHomeUniversityMap(List univApplyInfos) { + List homeUniversityIds = univApplyInfos.stream() + .map(UnivApplyInfo::getHomeUniversityId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + return homeUniversityRepository.findAllByIdIn(homeUniversityIds).stream() + .collect(Collectors.toMap(HomeUniversity::getId, Function.identity())); + } } diff --git a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java index a6a2b85f..5409f01e 100644 --- a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java +++ b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java @@ -6,13 +6,19 @@ 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.HomeUniversity; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponse; import com.example.solidconnection.university.dto.UnivApplyInfoRecommendsResponse; +import com.example.solidconnection.university.repository.HomeUniversityRepository; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,6 +30,7 @@ public class UnivApplyInfoRecommendService { public static final int RECOMMEND_UNIV_APPLY_INFO_NUM = 6; private final UnivApplyInfoRepository univApplyInfoRepository; + private final HomeUniversityRepository homeUniversityRepository; private final TermRepository termRepository; private final GeneralUnivApplyInfoRecommendService generalUnivApplyInfoRecommendService; @@ -50,12 +57,15 @@ public UnivApplyInfoRecommendsResponse getPersonalRecommends(long siteUserId) { trimmedRecommends.addAll(getGeneralRecommendsExcludingSelected(trimmedRecommends)); } + Map homeUniversityMap = getHomeUniversityMap(trimmedRecommends); + return new UnivApplyInfoRecommendsResponse(trimmedRecommends.stream() - .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( - univApplyInfo, - term.getName() - )) - .toList()); + .map(univApplyInfo -> { + HomeUniversity homeUniversity = homeUniversityMap.get(univApplyInfo.getHomeUniversityId()); + String homeUniversityName = homeUniversity != null ? homeUniversity.getName() : null; + return UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName(), homeUniversityName); + }) + .toList()); } private List getGeneralRecommendsExcludingSelected(List alreadyPicked) { @@ -76,11 +86,25 @@ public UnivApplyInfoRecommendsResponse getGeneralRecommends() { .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); List generalRecommends = new ArrayList<>(generalUnivApplyInfoRecommendService.getGeneralRecommends()); + Map homeUniversityMap = getHomeUniversityMap(generalRecommends); + return new UnivApplyInfoRecommendsResponse(generalRecommends.stream() - .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( - univApplyInfo, - term.getName() - )) - .toList()); + .map(univApplyInfo -> { + HomeUniversity homeUniversity = homeUniversityMap.get(univApplyInfo.getHomeUniversityId()); + String homeUniversityName = homeUniversity != null ? homeUniversity.getName() : null; + return UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName(), homeUniversityName); + }) + .toList()); + } + + private Map getHomeUniversityMap(List univApplyInfos) { + List homeUniversityIds = univApplyInfos.stream() + .map(UnivApplyInfo::getHomeUniversityId) + .filter(Objects::nonNull) + .distinct() + .toList(); + + return homeUniversityRepository.findAllByIdIn(homeUniversityIds).stream() + .collect(Collectors.toMap(HomeUniversity::getId, Function.identity())); } } From 26c86a1400f04cf9cf429ed391a6d04f06a994a2 Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 14:31:44 +0900 Subject: [PATCH 09/14] =?UTF-8?q?test:=20=EC=A7=80=EC=9B=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=99=20=EC=9D=91=EB=8B=B5=20=EC=88=98=EC=A0=95=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UnivApplyInfoQueryServiceTest.java | 22 ++++++------ .../UnivApplyInfoRecommendServiceTest.java | 34 ++++++++++--------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java index 2d776012..51e0586f 100644 --- a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java @@ -106,8 +106,8 @@ class 대학_지원_정보_텍스트_검색 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(메이지대학_지원_정보, term.getName()) + UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(메이지대학_지원_정보, term.getName(), null) ); } @@ -128,8 +128,8 @@ class 각각의_검색_대상에_대해_검색한다 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(메이지대학_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보, term.getName()) + UnivApplyInfoPreviewResponse.of(메이지대학_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(메모리얼대학_세인트존스_A_지원_정보, term.getName(), null) ); } @@ -147,8 +147,8 @@ class 각각의_검색_대상에_대해_검색한다 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(괌대학_B_지원_정보, term.getName()) + UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(괌대학_B_지원_정보, term.getName(), null) ); } @@ -166,8 +166,8 @@ class 각각의_검색_대상에_대해_검색한다 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(린츠_카톨릭대학_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(서던덴마크대학교_지원_정보, term.getName()) + UnivApplyInfoPreviewResponse.of(린츠_카톨릭대학_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(서던덴마크대학교_지원_정보, term.getName(), null) ); } } @@ -186,9 +186,9 @@ class 각각의_검색_대상에_대해_검색한다 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.from(대학지원정보_아, term.getName()), - UnivApplyInfoPreviewResponse.from(국가_아, term.getName()), - UnivApplyInfoPreviewResponse.from(권역_아, term.getName()) + UnivApplyInfoPreviewResponse.of(대학지원정보_아, term.getName(), null), + UnivApplyInfoPreviewResponse.of(국가_아, term.getName(), null), + UnivApplyInfoPreviewResponse.of(권역_아, term.getName(), null) ); } diff --git a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java index 9eeeb2c2..f2dfbe52 100644 --- a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java @@ -93,10 +93,10 @@ void setUp() { assertThat(response.recommendedUniversities()) .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsAll(List.of( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(괌대학_B_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(네바다주립대학_라스베이거스_지원_정보, term.getName()) + UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(괌대학_B_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(메모리얼대학_세인트존스_A_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(네바다주립대학_라스베이거스_지원_정보, term.getName(), null) )); } @@ -112,8 +112,8 @@ void setUp() { assertThat(response.recommendedUniversities()) .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsAll(List.of( - UnivApplyInfoPreviewResponse.from(서던덴마크대학교_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(코펜하겐IT대학_지원_정보, term.getName()) + UnivApplyInfoPreviewResponse.of(서던덴마크대학교_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(코펜하겐IT대학_지원_정보, term.getName(), null) )); } @@ -130,12 +130,12 @@ void setUp() { assertThat(response.recommendedUniversities()) .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsExactlyInAnyOrder( - UnivApplyInfoPreviewResponse.from(괌대학_A_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(괌대학_B_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(네바다주립대학_라스베이거스_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(서던덴마크대학교_지원_정보, term.getName()), - UnivApplyInfoPreviewResponse.from(코펜하겐IT대학_지원_정보, term.getName()) + UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(괌대학_B_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(메모리얼대학_세인트존스_A_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(네바다주립대학_라스베이거스_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(서던덴마크대학교_지원_정보, term.getName(), null), + UnivApplyInfoPreviewResponse.of(코펜하겐IT대학_지원_정보, term.getName(), null) ); } @@ -149,9 +149,10 @@ void setUp() { .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsExactlyInAnyOrderElementsOf( generalUnivApplyInfoRecommendService.getGeneralRecommends().stream() - .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.of( univApplyInfo, - term.getName() + term.getName(), + null )) .toList() ); @@ -167,9 +168,10 @@ void setUp() { .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsExactlyInAnyOrderElementsOf( generalUnivApplyInfoRecommendService.getGeneralRecommends().stream() - .map(univApplyInfo -> UnivApplyInfoPreviewResponse.from( + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.of( univApplyInfo, - term.getName() + term.getName(), + null )) .toList() ); From 0fbe7ed8026f8caacbcaa69c97bf3692c0228093 Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 16:03:28 +0900 Subject: [PATCH 10/14] =?UTF-8?q?refactor:=20=EA=B0=84=EC=A0=91=20?= =?UTF-8?q?=EC=B0=B8=EC=A1=B0=20=EB=8C=80=EC=8B=A0=20=EC=97=B0=EA=B4=80?= =?UTF-8?q?=EA=B4=80=EA=B3=84=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - N+1 방지를 위해 fetch join도 추가 --- .../university/domain/UnivApplyInfo.java | 6 ++-- .../dto/UnivApplyInfoPreviewResponse.java | 10 +++--- .../UnivApplyInfoFilterRepositoryImpl.java | 7 +++- .../service/LikedUnivApplyInfoService.java | 21 +----------- .../service/UnivApplyInfoQueryService.java | 25 +------------- .../UnivApplyInfoRecommendService.java | 33 ++----------------- 6 files changed, 19 insertions(+), 83 deletions(-) diff --git a/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java b/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java index a727a74e..64d264f3 100644 --- a/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java +++ b/src/main/java/com/example/solidconnection/university/domain/UnivApplyInfo.java @@ -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; @@ -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; diff --git a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java b/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java index d95dd120..1a6d1ce9 100644 --- a/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java +++ b/src/main/java/com/example/solidconnection/university/dto/UnivApplyInfoPreviewResponse.java @@ -17,17 +17,17 @@ public record UnivApplyInfoPreviewResponse( int studentCapacity, List languageRequirements) { - public static UnivApplyInfoPreviewResponse of( - UnivApplyInfo univApplyInfo, - String termName, - String homeUniversityName - ) { + public static UnivApplyInfoPreviewResponse of(UnivApplyInfo univApplyInfo, String termName) { List 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, diff --git a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java index 6347013a..cfb5e3a7 100644 --- a/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java +++ b/src/main/java/com/example/solidconnection/university/repository/custom/UnivApplyInfoFilterRepositoryImpl.java @@ -2,9 +2,10 @@ import com.example.solidconnection.location.country.domain.QCountry; import com.example.solidconnection.location.region.domain.QRegion; +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; @@ -33,6 +34,7 @@ public UnivApplyInfoFilterRepositoryImpl(EntityManager em) { public List findAllByRegionCodeAndKeywordsAndTermId(String regionCode, List keywords, Long termId) { QUnivApplyInfo univApplyInfo = QUnivApplyInfo.univApplyInfo; QHostUniversity university = QHostUniversity.hostUniversity; + QHomeUniversity homeUniversity = QHomeUniversity.homeUniversity; QCountry country = QCountry.country; QLanguageRequirement languageRequirement = QLanguageRequirement.languageRequirement; @@ -40,6 +42,7 @@ public List findAllByRegionCodeAndKeywordsAndTermId(String region .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) @@ -84,6 +87,7 @@ private BooleanExpression termIdEq(QUnivApplyInfo univApplyInfo, Long givenTermI public List 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; @@ -92,6 +96,7 @@ public List 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)); diff --git a/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java b/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java index d1b8b611..83ee9feb 100644 --- a/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java +++ b/src/main/java/com/example/solidconnection/university/service/LikedUnivApplyInfoService.java @@ -6,20 +6,16 @@ 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.HomeUniversity; import com.example.solidconnection.university.domain.LikedUnivApplyInfo; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.dto.IsLikeResponse; import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponse; -import com.example.solidconnection.university.repository.HomeUniversityRepository; import com.example.solidconnection.university.repository.LikedUnivApplyInfoRepository; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.function.Function; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -30,7 +26,6 @@ public class LikedUnivApplyInfoService { private final UnivApplyInfoRepository univApplyInfoRepository; - private final HomeUniversityRepository homeUniversityRepository; private final LikedUnivApplyInfoRepository likedUnivApplyInfoRepository; private final TermRepository termRepository; @@ -46,29 +41,15 @@ public List getLikedUnivApplyInfos(long siteUserId Map termMap = termRepository.findAllById(termIds).stream() .collect(Collectors.toMap(Term::getId, Term::getName)); - Map homeUniversityMap = getHomeUniversityMap(univApplyInfos); return univApplyInfos.stream() .map(univApplyInfo -> { String termName = termMap.getOrDefault(univApplyInfo.getTermId(), "Unknown"); - HomeUniversity homeUniversity = homeUniversityMap.get(univApplyInfo.getHomeUniversityId()); - String homeUniversityName = homeUniversity != null ? homeUniversity.getName() : null; - return UnivApplyInfoPreviewResponse.of(univApplyInfo, termName, homeUniversityName); + return UnivApplyInfoPreviewResponse.of(univApplyInfo, termName); }) .toList(); } - private Map getHomeUniversityMap(List univApplyInfos) { - List homeUniversityIds = univApplyInfos.stream() - .map(UnivApplyInfo::getHomeUniversityId) - .filter(Objects::nonNull) - .distinct() - .toList(); - - return homeUniversityRepository.findAllByIdIn(homeUniversityIds).stream() - .collect(Collectors.toMap(HomeUniversity::getId, Function.identity())); - } - /* * 대학교를 '좋아요' 한다. * */ diff --git a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java index 6c2c614d..5c11911a 100644 --- a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java +++ b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoQueryService.java @@ -7,19 +7,13 @@ 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.HomeUniversity; 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.UnivApplyInfoPreviewResponse; import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponses; -import com.example.solidconnection.university.repository.HomeUniversityRepository; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -29,7 +23,6 @@ public class UnivApplyInfoQueryService { private final UnivApplyInfoRepository univApplyInfoRepository; - private final HomeUniversityRepository homeUniversityRepository; private final TermRepository termRepository; /* @@ -55,26 +48,10 @@ public UnivApplyInfoPreviewResponses searchUnivApplyInfoByText(String text) { .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); List univApplyInfos = univApplyInfoRepository.findAllByText(text, term.getId()); - Map homeUniversityMap = getHomeUniversityMap(univApplyInfos); List responses = univApplyInfos.stream() - .map(univApplyInfo -> { - HomeUniversity homeUniversity = homeUniversityMap.get(univApplyInfo.getHomeUniversityId()); - String homeUniversityName = homeUniversity != null ? homeUniversity.getName() : null; - return UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName(), homeUniversityName); - }) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName())) .toList(); return new UnivApplyInfoPreviewResponses(responses); } - - private Map getHomeUniversityMap(List univApplyInfos) { - List homeUniversityIds = univApplyInfos.stream() - .map(UnivApplyInfo::getHomeUniversityId) - .filter(Objects::nonNull) - .distinct() - .toList(); - - return homeUniversityRepository.findAllByIdIn(homeUniversityIds).stream() - .collect(Collectors.toMap(HomeUniversity::getId, Function.identity())); - } } diff --git a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java index 5409f01e..872524d6 100644 --- a/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java +++ b/src/main/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendService.java @@ -6,19 +6,13 @@ 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.HomeUniversity; import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.dto.UnivApplyInfoPreviewResponse; import com.example.solidconnection.university.dto.UnivApplyInfoRecommendsResponse; -import com.example.solidconnection.university.repository.HomeUniversityRepository; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; -import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,7 +24,6 @@ public class UnivApplyInfoRecommendService { public static final int RECOMMEND_UNIV_APPLY_INFO_NUM = 6; private final UnivApplyInfoRepository univApplyInfoRepository; - private final HomeUniversityRepository homeUniversityRepository; private final TermRepository termRepository; private final GeneralUnivApplyInfoRecommendService generalUnivApplyInfoRecommendService; @@ -57,14 +50,8 @@ public UnivApplyInfoRecommendsResponse getPersonalRecommends(long siteUserId) { trimmedRecommends.addAll(getGeneralRecommendsExcludingSelected(trimmedRecommends)); } - Map homeUniversityMap = getHomeUniversityMap(trimmedRecommends); - return new UnivApplyInfoRecommendsResponse(trimmedRecommends.stream() - .map(univApplyInfo -> { - HomeUniversity homeUniversity = homeUniversityMap.get(univApplyInfo.getHomeUniversityId()); - String homeUniversityName = homeUniversity != null ? homeUniversity.getName() : null; - return UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName(), homeUniversityName); - }) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName())) .toList()); } @@ -86,25 +73,9 @@ public UnivApplyInfoRecommendsResponse getGeneralRecommends() { .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); List generalRecommends = new ArrayList<>(generalUnivApplyInfoRecommendService.getGeneralRecommends()); - Map homeUniversityMap = getHomeUniversityMap(generalRecommends); return new UnivApplyInfoRecommendsResponse(generalRecommends.stream() - .map(univApplyInfo -> { - HomeUniversity homeUniversity = homeUniversityMap.get(univApplyInfo.getHomeUniversityId()); - String homeUniversityName = homeUniversity != null ? homeUniversity.getName() : null; - return UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName(), homeUniversityName); - }) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName())) .toList()); } - - private Map getHomeUniversityMap(List univApplyInfos) { - List homeUniversityIds = univApplyInfos.stream() - .map(UnivApplyInfo::getHomeUniversityId) - .filter(Objects::nonNull) - .distinct() - .toList(); - - return homeUniversityRepository.findAllByIdIn(homeUniversityIds).stream() - .collect(Collectors.toMap(HomeUniversity::getId, Function.identity())); - } } From d77880616f84bdc96c961ac621e14c7e3627118f Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 16:20:07 +0900 Subject: [PATCH 11/14] =?UTF-8?q?test:=20=EA=B0=84=EC=A0=91=20=EC=B0=B8?= =?UTF-8?q?=EC=A1=B0=20=EB=B0=A9=EC=8B=9D=EC=97=90=EC=84=9C=20=EC=97=B0?= =?UTF-8?q?=EA=B4=80=20=EA=B4=80=EA=B3=84=20=EC=84=A4=EC=A0=95=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=94=B0=EB=A5=B8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UnivApplyInfoQueryServiceTest.java | 22 ++++++------ .../UnivApplyInfoRecommendServiceTest.java | 36 ++++++++----------- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java index 51e0586f..26f9772e 100644 --- a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoQueryServiceTest.java @@ -106,8 +106,8 @@ class 대학_지원_정보_텍스트_검색 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(메이지대학_지원_정보, term.getName(), null) + UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(메이지대학_지원_정보, term.getName()) ); } @@ -128,8 +128,8 @@ class 각각의_검색_대상에_대해_검색한다 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.of(메이지대학_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(메모리얼대학_세인트존스_A_지원_정보, term.getName(), null) + UnivApplyInfoPreviewResponse.of(메이지대학_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(메모리얼대학_세인트존스_A_지원_정보, term.getName()) ); } @@ -147,8 +147,8 @@ class 각각의_검색_대상에_대해_검색한다 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(괌대학_B_지원_정보, term.getName(), null) + UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(괌대학_B_지원_정보, term.getName()) ); } @@ -166,8 +166,8 @@ class 각각의_검색_대상에_대해_검색한다 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.of(린츠_카톨릭대학_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(서던덴마크대학교_지원_정보, term.getName(), null) + UnivApplyInfoPreviewResponse.of(린츠_카톨릭대학_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(서던덴마크대학교_지원_정보, term.getName()) ); } } @@ -186,9 +186,9 @@ class 각각의_검색_대상에_대해_검색한다 { // then assertThat(response.univApplyInfoPreviews()) .containsExactly( - UnivApplyInfoPreviewResponse.of(대학지원정보_아, term.getName(), null), - UnivApplyInfoPreviewResponse.of(국가_아, term.getName(), null), - UnivApplyInfoPreviewResponse.of(권역_아, term.getName(), null) + UnivApplyInfoPreviewResponse.of(대학지원정보_아, term.getName()), + UnivApplyInfoPreviewResponse.of(국가_아, term.getName()), + UnivApplyInfoPreviewResponse.of(권역_아, term.getName()) ); } diff --git a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java index f2dfbe52..b1aa7d24 100644 --- a/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java +++ b/src/test/java/com/example/solidconnection/university/service/UnivApplyInfoRecommendServiceTest.java @@ -93,10 +93,10 @@ void setUp() { assertThat(response.recommendedUniversities()) .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsAll(List.of( - UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(괌대학_B_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(메모리얼대학_세인트존스_A_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(네바다주립대학_라스베이거스_지원_정보, term.getName(), null) + UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(괌대학_B_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(메모리얼대학_세인트존스_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(네바다주립대학_라스베이거스_지원_정보, term.getName()) )); } @@ -112,8 +112,8 @@ void setUp() { assertThat(response.recommendedUniversities()) .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsAll(List.of( - UnivApplyInfoPreviewResponse.of(서던덴마크대학교_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(코펜하겐IT대학_지원_정보, term.getName(), null) + UnivApplyInfoPreviewResponse.of(서던덴마크대학교_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(코펜하겐IT대학_지원_정보, term.getName()) )); } @@ -130,12 +130,12 @@ void setUp() { assertThat(response.recommendedUniversities()) .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsExactlyInAnyOrder( - UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(괌대학_B_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(메모리얼대학_세인트존스_A_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(네바다주립대학_라스베이거스_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(서던덴마크대학교_지원_정보, term.getName(), null), - UnivApplyInfoPreviewResponse.of(코펜하겐IT대학_지원_정보, term.getName(), null) + UnivApplyInfoPreviewResponse.of(괌대학_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(괌대학_B_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(메모리얼대학_세인트존스_A_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(네바다주립대학_라스베이거스_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(서던덴마크대학교_지원_정보, term.getName()), + UnivApplyInfoPreviewResponse.of(코펜하겐IT대학_지원_정보, term.getName()) ); } @@ -149,11 +149,7 @@ void setUp() { .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsExactlyInAnyOrderElementsOf( generalUnivApplyInfoRecommendService.getGeneralRecommends().stream() - .map(univApplyInfo -> UnivApplyInfoPreviewResponse.of( - univApplyInfo, - term.getName(), - null - )) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName())) .toList() ); } @@ -168,11 +164,7 @@ void setUp() { .hasSize(RECOMMEND_UNIV_APPLY_INFO_NUM) .containsExactlyInAnyOrderElementsOf( generalUnivApplyInfoRecommendService.getGeneralRecommends().stream() - .map(univApplyInfo -> UnivApplyInfoPreviewResponse.of( - univApplyInfo, - term.getName(), - null - )) + .map(univApplyInfo -> UnivApplyInfoPreviewResponse.of(univApplyInfo, term.getName())) .toList() ); } From 2c63ea516846f845c9d82cac369888a4d4a41436 Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 16:34:56 +0900 Subject: [PATCH 12/14] =?UTF-8?q?chore:=20=EB=AA=A9=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=EC=97=90=EC=84=9C=20=EC=A7=80=EC=9B=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=99=20=ED=85=8C=EC=9D=B4=EB=B8=94=EC=97=90=20=ED=98=91?= =?UTF-8?q?=EC=A0=95=20=EB=8C=80=ED=95=99=20ID=EB=A5=BC=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=ED=95=98=EB=8F=84=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/data.sql | 44 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index ce4fca9c..3fa29bd0 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -148,81 +148,81 @@ VALUES (1, 'US', 'AMERICAS', 'University of Guam', 'university_of_guam', '괌대 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/bunkyo_gakuin_university/logo.png', 'https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/bunkyo_gakuin_university/1.png'); -INSERT INTO university_info_for_apply(term_id, university_id, korean_name, semester_requirement, student_capacity, +INSERT INTO university_info_for_apply(term_id, university_id, home_university_id, korean_name, semester_requirement, student_capacity, semester_available_for_dispatch, tuition_fee_type, details_for_major, details_for_apply, details_for_language, details_for_english_course, details_for_accommodation, details) -VALUES (1, 1, '괌대학(A형)', 2, 1, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, +VALUES (1, 1, 1, '괌대학(A형)', 2, 1, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, '외국어 성적 유효기간이 파견대학의 지원시까지 유효해야함', NULL, NULL, NULL), - (1, 1, '괌대학(B형)', 2, 2, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, + (1, 1, 1, '괌대학(B형)', 2, 2, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, '외국어 성적 유효기간이 파견대학의 지원시까지 유효해야함', NULL, NULL, '등록금 관련 정보: https://www.uog.edu/financial-aid/cost-to-attend'), - (1, 2, '네바다주립대학 라스베이거스(B형)', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', + (1, 2, 1, '네바다주립대학 라스베이거스(B형)', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '- 지원가능전공: 공학계열 관련 전공자
- 파견대학에 지원하는 전공과 본교 전공이 일치해야함', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- IELTS : 모든 영역에서 5.5 이상', NULL, NULL, ' - The Engineering International Programs (EIP) Programs 안의 글로벌 하이브리드 프로그램으로 선발됨
※ 하이브리드 프로그램: 정규 과목 + 비정규 General Education Courses 과목 수강으로 구성, 정규(약 6학점) / 비정규 (약 135시간 이상) 수업 수강 (세부사항 변동 가능)
- 기숙사가 있지만 기숙사 확정이 늦게 발표되고 전원보장이 어려워, 외부숙소로 진행될 수도 있음, 한 학기 기숙사 비용: 약 $4,500~$6,000
- 한 학기 등록금: 약 $7,500
- International Program and Service Fees $2,500'), - (1, 3, '메모리얼 대학 세인트존스(A형)', 2, 4, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 3, 1, '메모리얼 대학 세인트존스(A형)', 2, 4, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능
- 지원불가능전공: Medicine, Pharmacy, Social work, Nursing
- Computer Science, Music 지원 제한적', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야함
- TOEFL iBT : 읽기/쓰기 20점, 듣기/말하기 17점 이상
- IELTS : 모든 영역에서 6.0 이상
- 외국어 성적 유효기간이 파견대학의 학기 시작하는 날까지 유효해야함 ', NULL, NULL, NULL), - (1, 3, '메모리얼 대학 세인트존스(B형)', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', + (1, 3, 1, '메모리얼 대학 세인트존스(B형)', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능
- 지원불가능전공: Medicine, Pharmacy, Social work, Nursing
- Computer Science, Music 지원 제한적', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야함
- TOEFL iBT : 읽기/쓰기 20점, 듣기/말하기 17점 이상
- IELTS : 모든 영역에서 6.0 이상
- 외국어 성적 유효기간이 파견대학의 학기 시작하는 날까지 유효해야함 ', NULL, NULL, '국제학생 등록금 적용 (학점당 $2,080)'), - (1, 4, '서던퀸스랜드대학(B형)', 2, 5, 'ONE_SEMESTER', 'OVERSEAS_UNIVERSITY_PAYMENT', + (1, 4, 1, '서던퀸스랜드대학(B형)', 2, 5, 'ONE_SEMESTER', 'OVERSEAS_UNIVERSITY_PAYMENT', '- 타전공 지원 및 수강 가능
- 미술 계열, 간호학, 약학, 교육학 등 제한 있음
- 학과별 지원 자격요건이 있는 경우 모두 충족해야 하며, 사전 승인 필요', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- IELTS: 각 영역 최소 5.5 이상
- 외국어 성적 유효기간이 파견대학의 지원시까지 유효해야함 ', NULL, NULL, '서던퀸스랜드대학은 Trimester로 운영되므로 학사일정을 반드시 참고하길 바람
- In-state 등록금 납부
(등록금 관련 정보 : https://www.unisq.edu.au/international/partnerships/study-abroad-exchange/fees-scholarships)'), - (1, 5, '시드니대학', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', + (1, 5, 1, '시드니대학', 2, 5, 'IRRELEVANT', 'OVERSEAS_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능
- MECO, CAEL, LAWS unit 수강 여석 제한 있음', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야함
- IELTS: 모든 영역에서 6.0 이상
- TOEFL IBT: 읽기/듣기/말하기 17점, 쓰기 19점 이상
- 어학성적은 파견학기 시작시까지 유효하여야함', NULL, NULL, 'OSHC(Overseas Student Health Cover) 국제학생 보험가입 의무 (2023년 기준 AUD 348/학기, 학기마다 비용 상이)'), - (1, 6, '커틴대학(A형)', 2, 3, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 6, 1, '커틴대학(A형)', 2, 3, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능
지원 불가능 전공: Physiotherapy, Medicine, Nursing, Occupational Therapy ', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야함
- IELTS: 모든 영역에서 6.0 이상
- TOEFL IBT: 읽기 13점, 쓰기 21점, 듣기 13점, 말하기 18점 이상
- 어학성적은 파견학기 시작시까지 유효하여야함', NULL, NULL, '※ 24-1학기에 한하여 ''Destination Australia Cheung Kong Exchange Program Scholarship'' 지급 예정 (신청자 중 가장 총점이 우수한 학생 1명에게 AUD$6000 지급, 상세 내용은 국제처 홈페이지 해외대학정보 공지글 참고)'), - (1, 7, '서던덴마크대학교', 4, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', + (1, 7, 1, '서던덴마크대학교', 4, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '- 주전공과 지원전공이 반드시 일치할 필요는 없으나 본교에서 기초과목을 이수하여야 함
- 교환학생에게 제공되는 수업만 수강 가능
- Faculty of Engineering 내에서 2/3이상의 수업을 수강하여야 함
- 30 ECTS 수강', '- 어학성적표가 해당 대학 신청서 제출 시 유효하여야 함(~10월 1일)', NULL, NULL, '- 교외 숙소', NULL), - (1, 8, '코펜하겐 IT대학', 2, 2, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 8, 1, '코펜하겐 IT대학', 2, 2, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '- 본교 기초과목 이수사항에 따라 지원이 제한될 수 있으나 소속전공과 정확하게 일치 하지 않아도 지원은 가능(연관 전공이어야 함)
- 최소 7.5 ECTS, 최대 30ECTS 수강 가능
- 교차 수강 가능(선수과목이 지정되어있는 과목은 사전에 이수하여야 수강이 가능함)', '- 어학성적표가 해당 대학 신청서 제출 시 유효하여야 함(~11월 1일)', NULL, NULL, '- 제공(학교 운영 기숙사 아님)
- 선착순 배정', NULL), - (1, 9, '노이울름 대학', 2, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능', NULL, + (1, 9, 1, '노이울름 대학', 2, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '타전공 지원 및 수강 가능', NULL, '영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- TOEFL IBT: 읽기 18점; 듣기 17점, 말하기 20점, 쓰기 17점
- TOEIC: 읽기 385점, 듣기 400점, 말하기 160점, 쓰기 150점
외국어 성적 유효기간이 파견대학의 학기 시작하는 시점까지 유효해야 함', NULL, NULL, NULL), - (1, 10, '헐대학', 4, 3, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 10, 1, '헐대학', 4, 3, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '제한학과 많음. (Factsheet참조및Factsheet언급된 제한학과 외에도 학기마다 제한학과 발생가능성있음). 지원 전 권역 담당자랑 사전상담 요망. 학기당 30ECTS수강해야 LA승인남. 성적처리 늦은 편이라 8차 학기 수학자는 성적처리 늦은 거 감안하고 추가 이에 따른 불편함이 있음을 인지후 지원요망. ', '지원 전 권역 담당자와 사전상담 요망', '- 영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- TOEFL iBT : 듣기 및 쓰기 18점, 읽기 18점, 말하기 20점, 쓰기 18점 이상
- IELTS : 모든 영역에서 6.0이상', NULL, NULL, '영국 생활비 및 숙소비용 유럽권 지역 중 상대적으로 매우 높은편. 지원전 반드시 사전고려 요망'), - (1, 11, '그라츠 대학', 3, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '-주전공 혹은 제2전공(혹은 연계전공과) 유관학과여아 함', + (1, 11, 1, '그라츠 대학', 3, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '-주전공 혹은 제2전공(혹은 연계전공과) 유관학과여아 함', '선발인원 중 차순위 합격자는 학기제한(1개 학기)이 있을 수 있음', NULL, NULL, '학교인근 외부 숙소는 있지만, 외부업체운영숙소라 대학관할아님', NULL), - (1, 12, '그라츠공과대학', 2, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '-주전공 혹은 제2전공(혹은 연계전공과) 유관학과여아 함', + (1, 12, 1, '그라츠공과대학', 2, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '-주전공 혹은 제2전공(혹은 연계전공과) 유관학과여아 함', '선발인원 중 차순위 합격자는 학기제한(1개 학기)이 있을 수 있음', '- 영어 점수는 다음의 세부영역 점수를 각각 만족해야 함
- TOEFL IBT: 읽기 18점 이상, 쓰기 17점 이상, 말하기 20점 이상, 듣기 17점 이상
- IELTS: 쓰기 5.5점 이상, 말하기 6점 이상
''- TOEIC의 경우 S/W 점수 합산 310점 이상 ', NULL, '자체기숙사는 없음. 교환학생이 많이 지원한 학기에는 예약이 어려울 수도 있음(선착순 경우많음). 더블룸 기준약 한달에 € 340 per month (기숙사 종류게 따라 가격 차이 유) 예산잡으면됨.', NULL), - (1, 13, '린츠 카톨릭 대학교', 3, 2, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', + (1, 13, 1, '린츠 카톨릭 대학교', 3, 2, 'ONE_SEMESTER', 'HOME_UNIVERSITY_PAYMENT', '- 지원가능전공: History, Philosophy, Art History, theology
(영어과목 수가 그리 많지는 않으므로, 사전 확인필요)
''- 학기당 최소 15ECTS 수강신청해야 함', '봄학기에는 영어과목이 극히 제한적으로 열린다고 함. 지원 전 권역 담당자와 사전상담 요망', NULL, NULL, '학교에서 몇가지 기숙사 옵션 합격시 연결예정.', NULL), - (1, 14, '빈 공과대학교', 3, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', + (1, 14, 1, '빈 공과대학교', 3, 2, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '지원전공과 일치하지 않아도 지원가능하나 유사전공자만 지원가능하며, 본전공과 일치하지않으면 입학 및 수강에 불리할 수 있음
''-학기당 최소 15.ECTS 수강신청해야함', '선발인원 중 차순위 합격자는 학기제한(1개 학기)이 있을 수 있음', NULL, NULL, '기숙사없음', NULL), - (1, 15, 'IPSA', 4, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', + (1, 15, 1, 'IPSA', 4, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', '- 소속전공과 지원전공이 일치 또는 유사하여야 함 : 전공이 제한적이므로 반드시 홈페이지에서 지원 가능 전공을 확인할 것
- 최대 30ECTS 수강', '- 어학성적표가 해당 대학 신청서 제출 시 유효하여야 함(~11월 15일)', NULL, NULL, '- 미제공', NULL), - (1, 16, '메이지대학', 2, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', + (1, 16, 1, '메이지대학', 2, 3, 'IRRELEVANT', 'HOME_UNIVERSITY_PAYMENT', 'https://www.meiji.ac.jp/cip/english/admissions/co7mm90000000461-att/co7mm900000004d1.pdf', '*해당 학교 일정 상 10월초까지 서류제출 필요', '학부별로 기준 상이, 관련페이지 참조', NULL, NULL, NULL), - (1, 17, '바이카여자대학', 2, 1, 'IRRELEVANT', NULL, + (1, 17, 1, '바이카여자대학', 2, 1, 'IRRELEVANT', NULL, '교환학생 지원가능 : Department of Global English, Department of Japanese culture, Department of Media and Information, Department of Psychology.', '여학생만 신청가능', NULL, NULL, - '기숙사 없음, 계약된 외부 기숙사 사용-“Maison de Claire Ibaraki” 62,300엔/월, 2식 포함, 계약시 66,000엔 청구 (2023년 6월기준)', NULL), - (1, 18, '분쿄가쿠인대학', 2, 3, 'ONE_YEAR', 'HOME_UNIVERSITY_PAYMENT', NULL, NULL, NULL, NULL, + '기숙사 없음, 계약된 외부 기숙사 사용-"Maison de Claire Ibaraki" 62,300엔/월, 2식 포함, 계약시 66,000엔 청구 (2023년 6월기준)', NULL), + (1, 18, 1, '분쿄가쿠인대학', 2, 3, 'ONE_YEAR', 'HOME_UNIVERSITY_PAYMENT', NULL, NULL, NULL, NULL, '기숙사 보유, off campus, 식사 미제공, 45,000~50,000엔/월', NULL); INSERT INTO language_requirement(language_test_type, min_score, university_info_for_apply_id) From 1564227f68545000763d6dc21bc91f164bc0217a Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 16:43:55 +0900 Subject: [PATCH 13/14] =?UTF-8?q?test:=20home=20university=20fixture=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fixture/HomeUniversityFixture.java | 18 ++++++++++++ .../fixture/HomeUniversityFixtureBuilder.java | 29 +++++++++++++++++++ .../fixture/UnivApplyInfoFixture.java | 12 ++++++++ .../fixture/UnivApplyInfoFixtureBuilder.java | 11 +++++-- 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/example/solidconnection/university/fixture/HomeUniversityFixture.java create mode 100644 src/test/java/com/example/solidconnection/university/fixture/HomeUniversityFixtureBuilder.java diff --git a/src/test/java/com/example/solidconnection/university/fixture/HomeUniversityFixture.java b/src/test/java/com/example/solidconnection/university/fixture/HomeUniversityFixture.java new file mode 100644 index 00000000..97391a06 --- /dev/null +++ b/src/test/java/com/example/solidconnection/university/fixture/HomeUniversityFixture.java @@ -0,0 +1,18 @@ +package com.example.solidconnection.university.fixture; + +import com.example.solidconnection.university.domain.HomeUniversity; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.test.context.TestComponent; + +@TestComponent +@RequiredArgsConstructor +public class HomeUniversityFixture { + + private final HomeUniversityFixtureBuilder homeUniversityFixtureBuilder; + + public HomeUniversity 인하대학교() { + return homeUniversityFixtureBuilder.homeUniversity() + .name("인하대학교") + .create(); + } +} diff --git a/src/test/java/com/example/solidconnection/university/fixture/HomeUniversityFixtureBuilder.java b/src/test/java/com/example/solidconnection/university/fixture/HomeUniversityFixtureBuilder.java new file mode 100644 index 00000000..092b2a0c --- /dev/null +++ b/src/test/java/com/example/solidconnection/university/fixture/HomeUniversityFixtureBuilder.java @@ -0,0 +1,29 @@ +package com.example.solidconnection.university.fixture; + +import com.example.solidconnection.university.domain.HomeUniversity; +import com.example.solidconnection.university.repository.HomeUniversityRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.test.context.TestComponent; + +@TestComponent +@RequiredArgsConstructor +public class HomeUniversityFixtureBuilder { + + private final HomeUniversityRepository homeUniversityRepository; + + private String name; + + public HomeUniversityFixtureBuilder homeUniversity() { + return new HomeUniversityFixtureBuilder(homeUniversityRepository); + } + + public HomeUniversityFixtureBuilder name(String name) { + this.name = name; + return this; + } + + public HomeUniversity create() { + return homeUniversityRepository.findByName(name) + .orElseGet(() -> homeUniversityRepository.save(new HomeUniversity(null, name))); + } +} diff --git a/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixture.java b/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixture.java index fdfd1118..8fbfa8ab 100644 --- a/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixture.java +++ b/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixture.java @@ -10,12 +10,14 @@ public class UnivApplyInfoFixture { private final UnivApplyInfoFixtureBuilder univApplyInfoFixtureBuilder; private final UniversityFixture universityFixture; + private final HomeUniversityFixture homeUniversityFixture; public UnivApplyInfo 괌대학_A_지원_정보(long termId) { return univApplyInfoFixtureBuilder.univApplyInfo() .termId(termId) .koreanName("괌대학(A형)") .university(universityFixture.괌_대학()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -24,6 +26,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("괌대학(B형)") .university(universityFixture.괌_대학()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -32,6 +35,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("네바다주립대학 라스베이거스(B형)") .university(universityFixture.네바다주립_대학_라스베이거스()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -40,6 +44,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("아칸소 주립 대학") .university(universityFixture.아칸소_주립_대학()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -48,6 +53,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("메모리얼 대학 세인트존스(A형)") .university(universityFixture.메모리얼_대학_세인트존스()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -56,6 +62,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("서던덴마크대학교") .university(universityFixture.서던덴마크_대학()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -64,6 +71,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("코펜하겐 IT대학") .university(universityFixture.코펜하겐IT_대학()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -72,6 +80,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("그라츠 대학") .university(universityFixture.그라츠_대학()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -80,6 +89,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("그라츠공과대학") .university(universityFixture.그라츠공과_대학()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -88,6 +98,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("린츠 카톨릭 대학교") .university(universityFixture.린츠_카톨릭_대학()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } @@ -96,6 +107,7 @@ public class UnivApplyInfoFixture { .termId(termId) .koreanName("메이지대학") .university(universityFixture.메이지_대학()) + .homeUniversity(homeUniversityFixture.인하대학교()) .create(); } } diff --git a/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixtureBuilder.java b/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixtureBuilder.java index f304c2bd..2320f254 100644 --- a/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixtureBuilder.java +++ b/src/test/java/com/example/solidconnection/university/fixture/UnivApplyInfoFixtureBuilder.java @@ -3,8 +3,9 @@ import static com.example.solidconnection.university.domain.SemesterAvailableForDispatch.ONE_SEMESTER; import static com.example.solidconnection.university.domain.TuitionFeeType.HOME_UNIVERSITY_PAYMENT; -import com.example.solidconnection.university.domain.UnivApplyInfo; +import com.example.solidconnection.university.domain.HomeUniversity; import com.example.solidconnection.university.domain.HostUniversity; +import com.example.solidconnection.university.domain.UnivApplyInfo; import com.example.solidconnection.university.repository.UnivApplyInfoRepository; import java.util.HashSet; import lombok.RequiredArgsConstructor; @@ -19,6 +20,7 @@ public class UnivApplyInfoFixtureBuilder { private long termId; private String koreanName; private HostUniversity university; + private HomeUniversity homeUniversity; public UnivApplyInfoFixtureBuilder univApplyInfo() { return new UnivApplyInfoFixtureBuilder(univApplyInfoRepository); @@ -39,9 +41,14 @@ public UnivApplyInfoFixtureBuilder university(HostUniversity university) { return this; } + public UnivApplyInfoFixtureBuilder homeUniversity(HomeUniversity homeUniversity) { + this.homeUniversity = homeUniversity; + return this; + } + public UnivApplyInfo create() { UnivApplyInfo univApplyInfo = new UnivApplyInfo( - null, termId, null, koreanName, 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER, + null, termId, homeUniversity, koreanName, 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER, "1", "detailsForLanguage", "gpaRequirement", "gpaRequirementCriteria", "detailsForApply", "detailsForMajor", "detailsForAccommodation", "detailsForEnglishCourse", "details", From 7482dcf61da9a3cb99dd3c280addbc7c611b4a1d Mon Sep 17 00:00:00 2001 From: seonghyeok Date: Sun, 25 Jan 2026 16:55:12 +0900 Subject: [PATCH 14/14] =?UTF-8?q?refactor:=20home=20university=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20fetch=20join=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../university/repository/HomeUniversityRepository.java | 3 +++ .../repository/LikedUnivApplyInfoRepository.java | 7 ++++++- .../university/repository/UnivApplyInfoRepository.java | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/solidconnection/university/repository/HomeUniversityRepository.java b/src/main/java/com/example/solidconnection/university/repository/HomeUniversityRepository.java index 6ae63317..0cfc0593 100644 --- a/src/main/java/com/example/solidconnection/university/repository/HomeUniversityRepository.java +++ b/src/main/java/com/example/solidconnection/university/repository/HomeUniversityRepository.java @@ -2,9 +2,12 @@ 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 { List findAllByIdIn(List ids); + + Optional findByName(String name); } diff --git a/src/main/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepository.java b/src/main/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepository.java index 684703b5..e5a94d69 100644 --- a/src/main/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepository.java +++ b/src/main/java/com/example/solidconnection/university/repository/LikedUnivApplyInfoRepository.java @@ -17,8 +17,13 @@ public interface LikedUnivApplyInfoRepository extends JpaRepository 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 """) diff --git a/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java b/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java index 5bb56cfc..1cc25ee3 100644 --- a/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java +++ b/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java @@ -19,6 +19,7 @@ public interface UnivApplyInfoRepository extends JpaRepository