2.9 KiB
2.9 KiB
20260316_CanServiceGetCanUseStatusRefactoring.md
작업 목표
CanService.getCanUseStatus함수의 비효율적인 필터링 및 데이터 로딩 로직 개선.- Kotlin 레벨에서 수행하던 필터링을 DB 레벨(Querydsl)로 이동.
- Entity 전체를 조회하는 대신 필요한 필드만 조회(Query Projection)하도록 리팩토링.
작업 내용
CanService.getCanUseStatus현재 기능 검증용 테스트 코드 작성.UseCanQueryDto생성 (QueryProjection용 DTO).CanRepository에 Querydsl 기반의 고도화된getCanUseStatus추가 (또는 기존 메서드 수정).member.id필터링 (기존 유지).(can + rewardCan) > 0필터링.container(aos,ios,else)별paymentGateway필터링 (Join 사용).- 필요한 연관 엔티티(
Member,Room,AudioContent등)의 필드만 선택적으로 조회.
CanService.getCanUseStatus리팩토링.- 리포지토리에서 바로 DTO 또는 필요한 데이터만 받아오도록 수정.
- Kotlin
filter제거. - Kotlin
map로직 단순화 또는 QueryProjection으로 흡수 가능한지 판단하여 처리.
- 작성한 테스트 코드로 기능 검증.
- 테스트 코드에
@DisplayName추가 및 예외/엣지 케이스 테스트 보강. - 성능 및 쿼리 최적화 확인.
검증 결과
- 기능 검증:
CanServiceTest.kt를 작성하여 리팩토링 전후의 필터링 및 맵핑 로직이 동일하게 유지됨을 확인.@DisplayName을 추가하여 테스트 의도를 명확히 기술.- 유효하지 않은 타임존 입력 시
DateTimeException이 발생하는 예외 케이스 추가. - 데이터가 없을 때 빈 리스트 반환 및 각
CanUsage별 nullable 필드(닉네임, 제목 등)가 누락되었을 때의 기본 타이틀 처리 로직 검증.
- 성능 개선:
- Kotlin 레벨의 필터링을 DB 레벨(Querydsl)로 이동하여 불필요한 데이터 조회를 줄이고 페이지네이션 정확도 향상.
- Entity 전체 조회 대신 필요한 12개 필드만 조회하는
UseCanQueryDto사용 (Projection). CHANNEL_DONATION시 별도의 Member 조회를 위해 발생하던 N+1 또는 추가 쿼리를 Join을 통해 1번의 쿼리로 최적화.
- 코드 품질:
CanService에서 더 이상 사용하지 않는memberRepository의존성 제거.- 복잡한 맵핑 로직을 QueryProjection DTO 기반으로 깔끔하게 정리.
단계별 검증 내용
- 1차 구현 및 단위 테스트:
CanServiceTest를 통해aos,ios컨테이너별 필터링 조건이 올바르게 DB 쿼리에 반영되고 결과가 맵핑되는지 검증 (성공). - 쿼리 최적화 확인:
UseCanCalculate및 관련 엔티티들을leftJoin및innerJoin을 통해 한 번의 쿼리로 가져오도록 구현됨을 코드 레벨에서 확인.