Skip to content

Commit 8523757

Browse files
authored
♻️ Refactor - 회사 검색 시 조건을 중복 선택으로 변경하고 DB 조회성능을 튜닝한다
♻️ Refactor - 회사 검색 시 조건을 중복 선택으로 변경하고 DB 조회성능을 튜닝한다
2 parents c81dbe5 + 9606f8f commit 8523757

10 files changed

Lines changed: 97 additions & 30 deletions

File tree

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ dependencies {
105105

106106
//logging
107107
implementation "net.logstash.logback:logstash-logback-encoder:7.4"
108+
109+
//역직렬화
110+
implementation 'com.fasterxml.jackson.module:jackson-module-parameter-names'
108111
}
109112

110113
tasks.named('test') {

src/main/java/sopt/comfit/company/controller/CompanyController.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,25 @@ public class CompanyController implements CompanySwagger {
2626

2727
@Override
2828
public PageDto<GetCompanyListResponseDto> getCompanyList(@RequestParam(required = false) String keyword,
29-
@RequestParam(required = false) String industry,
30-
@RequestParam(required = false) String scale,
29+
@RequestParam(required = false) List<String> industry,
30+
@RequestParam(required = false) List<String> scale,
3131
@RequestParam(required = false) String sort,
3232
@RequestParam(defaultValue = "1") int page,
3333
@RequestParam(required = false) Boolean isRecruited) {
3434

3535
Pageable pageable = PageRequest.of(Math.max(page - 1, 0), 8);
36-
EIndustry industryEnum = industry != null ? EIndustry.from(industry) : null;
37-
EScale scaleEnum = scale != null ? EScale.valueOf(scale) : null;
36+
List<EIndustry> industryEnums = industry != null
37+
? industry.stream().map(EIndustry::from).toList()
38+
: null;
39+
40+
List<EScale> scaleEnums = scale != null
41+
? scale.stream().map(EScale::from).toList()
42+
: null;
43+
3844
ESort sortEnum = sort != null ? ESort.valueOf(sort) : null;
3945

4046

41-
return companyService.getCompanyList(keyword, industryEnum, scaleEnum, sortEnum, isRecruited, pageable);
47+
return companyService.getCompanyList(keyword, industryEnums, scaleEnums, sortEnum, isRecruited, pageable);
4248
}
4349

4450
@Override

src/main/java/sopt/comfit/company/controller/CompanySwagger.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ public interface CompanySwagger {
4444
@GetMapping
4545
@SecurityRequirement(name = "JWT")
4646
PageDto<GetCompanyListResponseDto> getCompanyList(@RequestParam(required = false) String keyword,
47-
@RequestParam(required = false) String industry,
48-
@RequestParam(required = false) String scale,
47+
@RequestParam(required = false) List<String> industry,
48+
@RequestParam(required = false) List<String> scale,
4949
@RequestParam(required = false) String sort,
5050
@RequestParam(defaultValue = "1") int page,
5151
@RequestParam(required = false) Boolean isRecruited);

src/main/java/sopt/comfit/company/domain/Company.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
@Entity
1111
@Getter
1212
@NoArgsConstructor(access = AccessLevel.PROTECTED)
13-
@Table(name = "companies")
13+
@Table(name = "companies", indexes = {
14+
@Index(name = "idx_company_industry_scale_created", columnList = "industry, scale, created_at DESC")
15+
})
1416
public class Company extends BaseTimeEntity {
1517
@Id
1618
@GeneratedValue(strategy = GenerationType.IDENTITY)

src/main/java/sopt/comfit/company/domain/CompanyRepositoryCustom.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
import sopt.comfit.global.enums.EIndustry;
77
import sopt.comfit.global.enums.ESort;
88

9+
import java.util.List;
10+
911
public interface CompanyRepositoryCustom {
1012

1113
Page<GetCompanyListResponseDto> getCompanyList(
1214
String keyword,
13-
EIndustry industry,
14-
EScale scale,
15+
List<EIndustry> industry,
16+
List<EScale> scale,
1517
Boolean isRecruited,
1618
ESort sort,
1719
Pageable pageable

src/main/java/sopt/comfit/company/domain/CompanyRepositoryImpl.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ public class CompanyRepositoryImpl implements CompanyRepositoryCustom {
2929
@Override
3030
public Page<GetCompanyListResponseDto> getCompanyList(
3131
String keyword,
32-
EIndustry industry,
33-
EScale scale,
32+
List<EIndustry> industry,
33+
List<EScale> scale,
3434
Boolean isRecruited,
3535
ESort sort,
3636
Pageable pageable
@@ -87,8 +87,8 @@ public Page<GetCompanyListResponseDto> getCompanyList(
8787

8888
private List<Company> sortByLikeCount(
8989
String keyword,
90-
EIndustry industry,
91-
EScale scale,
90+
List<EIndustry> industry,
91+
List<EScale> scale,
9292
Boolean isRecruited,
9393
Pageable pageable
9494
) {
@@ -143,12 +143,16 @@ private BooleanExpression keywordContains(String keyword) {
143143
: null;
144144
}
145145

146-
private BooleanExpression industryEq(EIndustry industry) {
147-
return industry != null ? company.industry.eq(industry) : null;
146+
private BooleanExpression industryEq(List<EIndustry> industry) {
147+
return industry != null && !industry.isEmpty()
148+
? company.industry.in(industry)
149+
: null;
148150
}
149151

150-
private BooleanExpression scaleEq(EScale scale) {
151-
return scale != null ? company.scale.eq(scale) : null;
152+
private BooleanExpression scaleEq(List<EScale> scale) {
153+
return scale != null && !scale.isEmpty()
154+
? company.scale.in(scale)
155+
: null;
152156
}
153157

154158
private BooleanExpression recruitingEq(Boolean isRecruited) {

src/main/java/sopt/comfit/company/domain/EScale.java

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,38 @@
22

33
import lombok.Getter;
44
import lombok.RequiredArgsConstructor;
5+
import sopt.comfit.company.exception.CompanyErrorCode;
6+
import sopt.comfit.global.enums.EIndustry;
7+
import sopt.comfit.global.exception.BaseException;
8+
import sopt.comfit.global.exception.CommonErrorCode;
9+
10+
import java.util.Arrays;
511

612
@Getter
713
@RequiredArgsConstructor
814
public enum EScale {
915

10-
LARGE("대기업"),
11-
STARTUP("스타트업"),
12-
PUBLIC_CORP("공기업"),
13-
MID_LARGE("중견기업"),
14-
SME("small and medium enterprise/중소기업"),
15-
FOREIGN("외국기업"),
16-
PUBLIC_ORG("공공기관"),
17-
ETC("기타");
16+
LARGE("LARGE", "대기업"),
17+
STARTUP("STARTUP","스타트업"),
18+
PUBLIC_CORP("PUBLIC_CORP", "공기업"),
19+
MID_LARGE("MID_LARGE", "중견기업"),
20+
SME("SME", "small and medium enterprise/중소기업"),
21+
FOREIGN("FOREIGN","외국기업"),
22+
PUBLIC_ORG("PUBLIC_ORG", "공공기관"),
23+
ETC("ETC", "기타");
1824

25+
private final String code;
1926
private final String description;
27+
28+
public static EScale from(String value) {
29+
30+
if(value == null){
31+
return null;
32+
}
33+
return Arrays.stream(values())
34+
.filter(eScale -> eScale.getCode().equals(value))
35+
.findFirst().orElseThrow(
36+
() -> BaseException.type(CompanyErrorCode.INVALID_KEYWORD)
37+
);
38+
}
2039
}

src/main/java/sopt/comfit/company/service/CompanyService.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package sopt.comfit.company.service;
22

33
import lombok.RequiredArgsConstructor;
4+
import org.springframework.cache.annotation.Cacheable;
45
import org.springframework.data.domain.Pageable;
56
import org.springframework.stereotype.Service;
67
import org.springframework.transaction.annotation.Transactional;
@@ -31,11 +32,14 @@ public class CompanyService {
3132
private final CompanyIssueRepository companyIssueRepository;
3233
private final UserRepository userRepository;
3334

34-
35+
@Cacheable(
36+
value = "companyList",
37+
key = "#keyword + '_' + #industry + '_' + #scale + '_' + #sort + '_' + #isRecruited + '_' + #pageable.pageNumber"
38+
)
3539
@Transactional(readOnly = true)
3640
public PageDto<GetCompanyListResponseDto> getCompanyList( String keyword,
37-
EIndustry industry,
38-
EScale scale,
41+
List<EIndustry> industry,
42+
List<EScale> scale,
3943
ESort sort,
4044
Boolean isRecruited,
4145
Pageable pageable){

src/main/java/sopt/comfit/global/config/RedisConfig.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
package sopt.comfit.global.config;
22

3+
import org.springframework.cache.annotation.EnableCaching;
34
import org.springframework.context.annotation.Bean;
45
import org.springframework.context.annotation.Configuration;
6+
import org.springframework.data.redis.cache.RedisCacheConfiguration;
7+
import org.springframework.data.redis.cache.RedisCacheManager;
58
import org.springframework.data.redis.connection.RedisConnectionFactory;
69
import org.springframework.data.redis.core.RedisTemplate;
10+
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
11+
import org.springframework.data.redis.serializer.RedisSerializationContext;
712
import org.springframework.data.redis.serializer.StringRedisSerializer;
813

14+
import java.time.Duration;
15+
16+
@EnableCaching
917
@Configuration
1018
public class RedisConfig {
1119

@@ -23,4 +31,18 @@ public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factor
2331

2432
return redisTemplate;
2533
}
34+
35+
@Bean
36+
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
37+
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
38+
.entryTtl(Duration.ofMinutes(10))
39+
.serializeKeysWith(RedisSerializationContext.SerializationPair
40+
.fromSerializer(new StringRedisSerializer()))
41+
.serializeValuesWith(RedisSerializationContext.SerializationPair
42+
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
43+
44+
return RedisCacheManager.builder(factory)
45+
.cacheDefaults(config)
46+
.build();
47+
}
2648
}

src/main/java/sopt/comfit/report/domain/AIReportRepository.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ Page<AIReport> findByExperienceUserIdAndKeyword(
2323
Pageable pageable
2424
);
2525

26-
Optional<AIReport> findByExperienceUserIdAndId(Long userId, Long id);
26+
@Query("SELECT a FROM AIReport a " +
27+
"JOIN FETCH a.company " +
28+
"JOIN FETCH a.experience " +
29+
"WHERE a.experience.user.id = :userId AND a.id = :id")
30+
Optional<AIReport> findByExperienceUserIdAndId(@Param("userId") Long userId, @Param("id") Long id);
31+
2732
boolean existsByCompanyIdAndExperienceUserId(Long companyId, Long userId);
2833
}

0 commit comments

Comments
 (0)