Skip to content

Commit

Permalink
Merge pull request #188 from ITZipProject/feature/job-info-scrap
Browse files Browse the repository at this point in the history
๐Ÿš‘ ๊ธด๊ธ‰ ์ˆ˜์ • :  ์ฑ„์šฉ์ •๋ณด ์ง€์—ญ ์ •๋ณด ํ•„ํ„ฐ๋ง ๊ฒ€์ƒ‰ ๋ฏธ๊ตฌํ˜„ ์ฝ”๋“œ ๊ตฌํ˜„์™„๋ฃŒ
  • Loading branch information
hanseu9839 authored Dec 5, 2024
2 parents 92508ed + eac1b45 commit 64cc5d1
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ public class JobInfoController {
@ResponseCodeAnnotation(CommonResponseCode.SUCCESS)
@ExceptionCodeAnnotations(CommonExceptionCode.BAD_REQUEST)
@GetMapping("")
public Page<JobInfoSearchResponse> searchJobInfo(@Parameter(description = "๊ฒ€์ƒ‰์–ด") @RequestParam(value = "search", required = false) String search, @Parameter(description = "๊ธฐ์ˆ  ์ •๋ณด ํ•„ํ„ฐ") @RequestParam(value = "techName", required = false) String category, @Parameter(description = "๊ฒฝ๋ ฅ ์ตœ์†Œ ๊ฐ’") @RequestParam(value = "experienceMin", required = false) Integer experienceMin, @Parameter(description = "์ง€์—ญ์ •๋ณด") @RequestParam(required = false) String location, @Parameter(description = "๊ฒฝ๋ ฅ ์ตœ๋Œ€ ๊ฐ’") @RequestParam(value = "experienceMax", required = false) Integer experienceMax, @Parameter(description = "Size : ํŽ˜์ด์ง€๋‹น ์ถœ๋ ฅํ•  ํ•ญ๋ชฉ์˜ ๊ฐœ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’: 10) \n sort`: ์ •๋ ฌ ๊ธฐ์ค€ ํ•„๋“œ (๊ธฐ๋ณธ๊ฐ’: `scrap`) \n direction`: ์ •๋ ฌ ์ˆœ์„œ (๊ธฐ๋ณธ๊ฐ’: ๋‚ด๋ฆผ์ฐจ์ˆœ `DESC`)") @PageableDefault(size = 10, sort = "scrap", direction = Sort.Direction.DESC) Pageable pageable) {
public Page<JobInfoSearchResponse> searchJobInfo(@Parameter(description = "๊ฒ€์ƒ‰์–ด") @RequestParam(value = "search", required = false) String search, @Parameter(description = "๊ธฐ์ˆ  ์ •๋ณด ํ•„ํ„ฐ") @RequestParam(value = "techName", required = false) String category, @Parameter(description = "๊ฒฝ๋ ฅ ์ตœ์†Œ ๊ฐ’") @RequestParam(value = "experienceMin", required = false) Integer experienceMin, @Parameter(description = "์ง€์—ญ์ •๋ณด") @RequestParam(required = false) String locationCode, @Parameter(description = "๊ฒฝ๋ ฅ ์ตœ๋Œ€ ๊ฐ’") @RequestParam(value = "experienceMax", required = false) Integer experienceMax, @Parameter(description = "Size : ํŽ˜์ด์ง€๋‹น ์ถœ๋ ฅํ•  ํ•ญ๋ชฉ์˜ ๊ฐœ์ˆ˜ (๊ธฐ๋ณธ๊ฐ’: 10) \n sort`: ์ •๋ ฌ ๊ธฐ์ค€ ํ•„๋“œ (๊ธฐ๋ณธ๊ฐ’: `scrap`) \n direction`: ์ •๋ ฌ ์ˆœ์„œ (๊ธฐ๋ณธ๊ฐ’: ๋‚ด๋ฆผ์ฐจ์ˆœ `DESC`)") @PageableDefault(size = 10, sort = "scrap", direction = Sort.Direction.DESC) Pageable pageable) {

return jobInfoService.searchJobInfo(search, category, experienceMin, experienceMax, location, pageable);
return jobInfoService.searchJobInfo(search, category, experienceMin, experienceMax, locationCode, pageable);
}

@Operation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import darkoverload.itzip.feature.job.controller.response.JobInfoSearchResponse;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;

public interface CustomJobInfoRepository {
long bulkDeleteByPositionIds(List<Long> positionIds);

Page<JobInfoSearchResponse> searchJobInfo(String search, String category, Integer experienceMin, Integer experienceMax, Pageable pageable);
Page<JobInfoSearchResponse> searchJobInfo(String search, String category, Integer experienceMin, Integer experienceMax, String locationName, Pageable pageable);

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static org.springframework.util.StringUtils.hasText;

@Repository
@RequiredArgsConstructor
public class CustomJobInfoRepositoryImpl implements CustomJobInfoRepository {
Expand All @@ -35,23 +37,23 @@ public long bulkDeleteByPositionIds(List<Long> positionIds) {

/**
* ์ฃผ์–ด์ง„ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ฑ„์šฉ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฉ”์„œ๋“œ.
*
* <p>
* 1. ๊ฒ€์ƒ‰ ์กฐ๊ฑด (๊ฒ€์ƒ‰์–ด, ์นดํ…Œ๊ณ ๋ฆฌ, ์ตœ์†Œ ๋ฐ ์ตœ๋Œ€ ๊ฒฝ๋ ฅ)์— ๋”ฐ๋ผ ์กฐ๊ฑด์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
* 2. ์ •๋ ฌ ์กฐ๊ฑด์„ ์ ์šฉํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ์ •๋ ฌํ•ฉ๋‹ˆ๋‹ค.
* 3. ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ, ํŽ˜์ด์ง€ ํฌ๊ธฐ ๋ฐ ์ •๋ ฌ ์กฐ๊ฑด์„ ๋ฐ˜์˜ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
* 4. ํŽ˜์ด์ง•๋œ ์ฑ„์šฉ ์ •๋ณด ๋ชฉ๋ก๊ณผ ์ „์ฒด ๋ ˆ์ฝ”๋“œ ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
*
* @param search String: ๊ฒ€์ƒ‰์–ด (์ฑ„์šฉ ์ •๋ณด์˜ ์ œ๋ชฉ ๋˜๋Š” ๊ธฐํƒ€ ํ•„๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฒ€์ƒ‰)
* @param category String: ์นดํ…Œ๊ณ ๋ฆฌ (ํ•ด๋‹น ์นดํ…Œ๊ณ ๋ฆฌ์— ์†ํ•˜๋Š” ์ฑ„์šฉ ์ •๋ณด๋ฅผ ํ•„ํ„ฐ๋ง)
* @param search String: ๊ฒ€์ƒ‰์–ด (์ฑ„์šฉ ์ •๋ณด์˜ ์ œ๋ชฉ ๋˜๋Š” ๊ธฐํƒ€ ํ•„๋“œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฒ€์ƒ‰)
* @param category String: ์นดํ…Œ๊ณ ๋ฆฌ (ํ•ด๋‹น ์นดํ…Œ๊ณ ๋ฆฌ์— ์†ํ•˜๋Š” ์ฑ„์šฉ ์ •๋ณด๋ฅผ ํ•„ํ„ฐ๋ง)
* @param experienceMin Integer: ์ตœ์†Œ ๊ฒฝ๋ ฅ (ํ•ด๋‹น ๊ฐ’ ์ด์ƒ ๊ฒฝ๋ ฅ์„ ๊ฐ€์ง„ ์ฑ„์šฉ ์ •๋ณด๋ฅผ ํ•„ํ„ฐ๋ง)
* @param experienceMax Integer: ์ตœ๋Œ€ ๊ฒฝ๋ ฅ (ํ•ด๋‹น ๊ฐ’ ์ดํ•˜ ๊ฒฝ๋ ฅ์„ ๊ฐ€์ง„ ์ฑ„์šฉ ์ •๋ณด๋ฅผ ํ•„ํ„ฐ๋ง)
* @param pageable Pageable: ํŽ˜์ด์ง€ ์ •๋ณด์™€ ์ •๋ ฌ ์กฐ๊ฑด์„ ํฌํ•จํ•œ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ ์ •๋ณด (ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ, ํŽ˜์ด์ง€ ํฌ๊ธฐ, ์ •๋ ฌ ์กฐ๊ฑด)
* @param pageable Pageable: ํŽ˜์ด์ง€ ์ •๋ณด์™€ ์ •๋ ฌ ์กฐ๊ฑด์„ ํฌํ•จํ•œ ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ ์ •๋ณด (ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ, ํŽ˜์ด์ง€ ํฌ๊ธฐ, ์ •๋ ฌ ์กฐ๊ฑด)
* @return Page<JobInfoSearchResponse>: ํŽ˜์ด์ง•๋œ ์ฑ„์šฉ ์ •๋ณด ๋ชฉ๋ก์„ ๋ฐ˜ํ™˜
*/
@Override
public Page<JobInfoSearchResponse> searchJobInfo(String search, String category, Integer experienceMin, Integer experienceMax, Pageable pageable) {
public Page<JobInfoSearchResponse> searchJobInfo(String search, String category, Integer experienceMin, Integer experienceMax, String locationCode, Pageable pageable) {
// ๊ฒ€์ƒ‰ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ Where ์ ˆ ์ƒ์„ฑ
BooleanExpression whereClause = createWhereClause(search, category, experienceMin, experienceMax);
BooleanExpression whereClause = createWhereClause(search, category, experienceMin, experienceMax, locationCode);

// Pageable์—์„œ ์ •๋ ฌ ์กฐ๊ฑด์„ ์ถ”์ถœํ•˜์—ฌ ์ ์šฉ
OrderSpecifier<?>[] sortOrder = createSortOrder(pageable);
Expand Down Expand Up @@ -99,33 +101,34 @@ public Page<JobInfoSearchResponse> searchJobInfo(String search, String category,

/**
* ์ฃผ์–ด์ง„ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ ์œผ๋กœ WHERE ์ ˆ์„ ์ƒ์„ฑํ•˜๋Š” ๋ฉ”์„œ๋“œ.
*
* <p>
* 1. ๊ฒ€์ƒ‰์–ด, ์นดํ…Œ๊ณ ๋ฆฌ, ์ตœ์†Œ ๊ฒฝ๋ ฅ, ์ตœ๋Œ€ ๊ฒฝ๋ ฅ ์กฐ๊ฑด์„ ๋™์ ์œผ๋กœ ๊ฒฐํ•ฉํ•˜์—ฌ WHERE ์ ˆ์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
* 2. ๊ฐ๊ฐ์˜ ์กฐ๊ฑด์ด `null`์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์กฐ๊ฑด์ด ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น ์กฐ๊ฑด์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
* 3. ์—ฌ๋Ÿฌ ์กฐ๊ฑด์„ ์กฐํ•ฉํ•˜๊ธฐ ์œ„ํ•ด QueryDSL์˜ `Expressions.allOf()`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
*
* @param search String: ๊ฒ€์ƒ‰์–ด (null ๊ฐ€๋Šฅ, ํŠน์ • ํ‚ค์›Œ๋“œ๋กœ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์‚ฌ์šฉ)
* @param category String: ์นดํ…Œ๊ณ ๋ฆฌ (null ๊ฐ€๋Šฅ, ํŠน์ • ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ํ•„ํ„ฐ๋งํ•  ๋•Œ ์‚ฌ์šฉ)
* @param search String: ๊ฒ€์ƒ‰์–ด (null ๊ฐ€๋Šฅ, ํŠน์ • ํ‚ค์›Œ๋“œ๋กœ ๊ฒ€์ƒ‰ํ•  ๋•Œ ์‚ฌ์šฉ)
* @param category String: ์นดํ…Œ๊ณ ๋ฆฌ (null ๊ฐ€๋Šฅ, ํŠน์ • ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ํ•„ํ„ฐ๋งํ•  ๋•Œ ์‚ฌ์šฉ)
* @param experienceMin Integer: ์ตœ์†Œ ๊ฒฝ๋ ฅ (null ๊ฐ€๋Šฅ, ์ด ๊ฐ’ ์ด์ƒ ๊ฒฝ๋ ฅ์˜ ์ฑ„์šฉ ์ •๋ณด๋ฅผ ํ•„ํ„ฐ๋ง)
* @param experienceMax Integer: ์ตœ๋Œ€ ๊ฒฝ๋ ฅ (null ๊ฐ€๋Šฅ, ์ด ๊ฐ’ ์ดํ•˜ ๊ฒฝ๋ ฅ์˜ ์ฑ„์šฉ ์ •๋ณด๋ฅผ ํ•„ํ„ฐ๋ง)
* @return BooleanExpression: ๋™์ ์œผ๋กœ ์ƒ์„ฑ๋œ ๊ฒ€์ƒ‰ ์กฐ๊ฑด์„ ํฌํ•จํ•œ WHERE ์ ˆ
*/
private BooleanExpression createWhereClause(String search, String category, Integer experienceMin, Integer experienceMax) {
private BooleanExpression createWhereClause(String search, String category, Integer experienceMin, Integer experienceMax, String locationCode) {
return Expressions.allOf(
searchEq(search),
categoryEq(category),
experienceMinGoe(experienceMin),
experienceMaxLoe(experienceMax)
experienceMaxLoe(experienceMax),
searchLocationCodeEq(locationCode)
);
}

/**
* Pageable ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ์ •๋ ฌ ์ •๋ณด๋ฅผ ์ถ”์ถœํ•˜์—ฌ QueryDSL์˜ OrderSpecifier ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜๋Š” ๋ฉ”์„œ๋“œ.
*
* <p>
* 1. Pageable ๊ฐ์ฒด์— ํฌํ•จ๋œ Sort ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ •๋ ฌ ํ•„๋“œ๋ฅผ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
* 2. ๊ฐ ํ•„๋“œ์— ๋Œ€ํ•ด ์˜ค๋ฆ„์ฐจ์ˆœ ๋˜๋Š” ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
* 3. ํ•„๋“œ๋ช…์ด "modifyDate" ๋˜๋Š” "scrap"์ธ ๊ฒฝ์šฐ์—๋งŒ ์ •๋ ฌ ์กฐ๊ฑด์„ ์„ค์ •ํ•˜๋ฉฐ,
* ๊ทธ ์™ธ ํ•„๋“œ๋Š” ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ  null์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
* ๊ทธ ์™ธ ํ•„๋“œ๋Š” ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ  null์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
* 4. null ๊ฐ’์„ ํ•„ํ„ฐ๋งํ•˜์—ฌ ์œ ํšจํ•œ ์ •๋ ฌ ์กฐ๊ฑด๋งŒ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
*
* @param pageable Pageable: ํŽ˜์ด์ง€ ์ •๋ณด์™€ ์ •๋ ฌ ์กฐ๊ฑด์„ ํฌํ•จํ•˜๋Š” ๊ฐ์ฒด
Expand All @@ -150,6 +153,19 @@ private OrderSpecifier<?>[] createSortOrder(Pageable pageable) {
.toArray(OrderSpecifier[]::new); // ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ˜ํ™˜
}

private BooleanExpression searchLocationCodeEq(String locationCode) {
if(!hasText(locationCode)) {
return null;
}
String[] locationCodeArr = locationCode.split(",");


return Arrays.stream(locationCodeArr)
.map(name-> jobInfoEntity.locationCode.contains(name))
.reduce(BooleanExpression::or)
.orElse(null);
}

// ๊ฒ€์ƒ‰์–ด ์กฐ๊ฑด
private BooleanExpression searchEq(String search) {
return hasText(search) ? jobInfoEntity.title.contains(search) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.util.Set;

public interface JobInfoService {
Page<JobInfoSearchResponse> searchJobInfo(String search, String techName, Integer experienceMin, Integer experienceMax, String location, Pageable pageable);
Page<JobInfoSearchResponse> searchJobInfo(String search, String techName, Integer experienceMin, Integer experienceMax, String locationCode, Pageable pageable);

JobInfo getById(Long jobInfoId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class JobInfoServiceImpl implements JobInfoService{
@Override
public Page<JobInfoSearchResponse> searchJobInfo(String search, String category, Integer experienceMin, Integer experienceMax, String locationName, Pageable pageable) {

return jobInfoRepository.searchJobInfo(search, category, experienceMin, experienceMax, pageable);
return jobInfoRepository.searchJobInfo(search, category, experienceMin, experienceMax, locationName, pageable);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class JobInfoRepositoryTest {
@Test
void ์ฑ„์šฉ์ •๋ณด_ํŽ˜์ด์ง•_์กฐํšŒ() {
Pageable pageable = PageRequest.of(0, 10);
Page<JobInfoSearchResponse> jobInfoSearchResponses = repository.searchJobInfo("LG", "๋ชจ๋ฐ”์ผ", 0, null, pageable);
Page<JobInfoSearchResponse> jobInfoSearchResponses = repository.searchJobInfo("LG", "๋ชจ๋ฐ”์ผ", 0, null, null,pageable);
List<String> jobNameList = Arrays.asList("CDMA","๋ชจ๋ฐ”์ผ","๋ฌด์„ ํ†ต์‹ ","ํ…”๋ ˆ์ฝค","ํ†ต์‹ ","๋„คํŠธ์›Œํฌ","์ •๋ณดํ†ต์‹ ","์†”๋ฃจ์…˜");


Expand Down

0 comments on commit 64cc5d1

Please sign in to comment.