Skip to content

Commit

Permalink
[feat] jpa specification에서 발생하던 N+1 / fetch 안되는 문제를 queryDSL로 해결(#135)
Browse files Browse the repository at this point in the history
  • Loading branch information
blaxsior committed Aug 22, 2024
1 parent 3a5ffe1 commit fdeb66e
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 35 deletions.
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ dependencies {

// sms api
implementation 'net.nurigo:sdk:4.3.0'

// queryDsl
implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
annotationProcessor "jakarta.annotation:jakarta.annotation-api"
annotationProcessor "jakarta.persistence:jakarta.persistence-api"

}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class AdminEventUserController {
@GetMapping
public ResponseEntity<EventUserPageDto> getEventUsers(
@RequestParam(name="search", required = false, defaultValue = "") String search,
@RequestParam(name="field", required = false, defaultValue = "name") String field,
@RequestParam(name="field", required = false, defaultValue = "userName") String field,
@RequestParam(name="page", required = false, defaultValue = "0") @Min(0) Integer page,
@RequestParam(name="size", required = false, defaultValue = "10") @Min(1) Integer size
) {
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/hyundai/softeer/orange/config/QueryDSLConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package hyundai.softeer.orange.config;


import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@RequiredArgsConstructor
public class QueryDSLConfig {
private final EntityManager entityManager;

@Bean
public JPAQueryFactory jpaQueryFactory(){
return new JPAQueryFactory(entityManager);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package hyundai.softeer.orange.eventuser.repository;

import hyundai.softeer.orange.eventuser.dto.EventUserScoreDto;
import hyundai.softeer.orange.eventuser.entity.EventUser;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.Collection;
import java.util.List;

public interface CustomEventUserRepository {
void updateScoreMany(List<EventUserScoreDto> dto);
Page<EventUser> findBySearch(String search, String field, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package hyundai.softeer.orange.eventuser.repository;

import com.querydsl.jpa.impl.JPAQueryFactory;
import hyundai.softeer.orange.event.common.entity.QEventFrame;
import hyundai.softeer.orange.eventuser.dto.EventUserScoreDto;
import hyundai.softeer.orange.eventuser.entity.EventUser;
import hyundai.softeer.orange.eventuser.entity.QEventUser;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
Expand All @@ -14,6 +21,7 @@
@Repository
public class CustomEventUserRepositoryImpl implements CustomEventUserRepository {
private final JdbcTemplate jdbcTemplate;
private final JPAQueryFactory queryFactory;

@Override
public void updateScoreMany(List<EventUserScoreDto> userScores) {
Expand All @@ -33,4 +41,22 @@ public int getBatchSize() {
}
});
}

@Override
public Page<EventUser> findBySearch(String search, String field, Pageable pageable) {
QEventUser user = QEventUser.eventUser;
QEventFrame eventFrame = QEventFrame.eventFrame;

var query = queryFactory.select(user)
.from(user)
.leftJoin(user.eventFrame, eventFrame)
.fetchJoin();

if("userName".equals(field)) query.where(user.userName.contains(search));
else if("phoneNumber".equals(field))query.where(user.phoneNumber.contains(search));
else if("frameId".equals(field)) query.where(user.eventFrame.frameId.contains(search));

var data = query.offset(pageable.getOffset()).limit(pageable.getPageSize()).fetch();
return new PageImpl<>(data, pageable, data.size());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,17 @@
import hyundai.softeer.orange.core.jwt.JWTManager;
import hyundai.softeer.orange.event.common.entity.EventFrame;
import hyundai.softeer.orange.event.common.repository.EventFrameRepository;
import hyundai.softeer.orange.eventuser.dto.EventUserOnAdminDto;
import hyundai.softeer.orange.eventuser.dto.EventUserPageDto;
import hyundai.softeer.orange.eventuser.dto.RequestAuthCodeDto;
import hyundai.softeer.orange.eventuser.dto.RequestUserDto;
import hyundai.softeer.orange.eventuser.entity.EventUser;
import hyundai.softeer.orange.eventuser.exception.EventUserException;
import hyundai.softeer.orange.eventuser.repository.EventUserRepository;
import hyundai.softeer.orange.eventuser.repository.EventUserSpecification;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand Down Expand Up @@ -57,13 +53,7 @@ public TokenDto login(RequestUserDto dto) {
@Transactional(readOnly = true)
public EventUserPageDto getUserBySearch(String search, String field, int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size);

Specification<EventUser> searchSpec = EventUserSpecification.search(search, field);

Page<EventUser> userPage = eventUserRepository.findBy(
searchSpec,
(q) -> q.page(pageRequest)
);
Page<EventUser> userPage = eventUserRepository.findBySearch(search, field, pageRequest);

return EventUserPageDto.from(userPage);
}
Expand Down

0 comments on commit fdeb66e

Please sign in to comment.