TIL - 20250812

juni·2025년 8월 12일

TIL

목록 보기
92/317

0812 여행 관리 기능 개발: 데이터 모델링부터 동적 쿼리, 프론트엔드 라우팅까지


✅ 1. 여행 데이터 모델링 및 Repository 구축

  • 여행 관리 기능의 기반을 마련하기 위해 Trip 엔터티TripStatus 열거형(Enum)을 추가했습니다.
  1. Trip 엔터티:

    • 주요 필드: 여행 제목, 설명, 기간(시작/종료일), 예산, 목적지 등 여행의 핵심 정보를 관리합니다.
    • 관계 매핑: User 엔터티와 다대일(N:1) 관계를 설정하여, 어떤 사용자의 여행인지 명확히 했습니다.
    • 상태 관리: 여행의 현재 상태(PLANNING, ONGOING, COMPLETED, CANCELLED)를 관리하기 위해 TripStatus Enum을 필드로 사용합니다.
    • 자동 시간 기록: @CreationTimestamp, @UpdateTimestamp를 사용하여 생성 및 수정 시간을 자동으로 기록합니다.
  2. TripRepository:

    • JpaRepository를 상속받아 기본적인 CRUD 기능을 확보했습니다. 이 Repository는 여행 데이터의 영속성을 관리하는 핵심 인터페이스입니다.

✅ 2. QueryDSL을 활용한 동적 검색 기능 구현

  • 사용자의 다양한 검색 조건(여행 상태, 목적지, 제목)과 정렬 기준에 따라 여행 목록을 조회할 수 있도록 QueryDSL을 도입하여 동적 쿼리 기능을 구현했습니다.

➕ 구현 단계

  1. QueryDSL 설정: build.gradle에 QueryDSL 의존성을 추가하고, JPAQueryFactory를 Spring Bean으로 등록하는 QueryDslConfig를 설정했습니다.
  2. 커스텀 Repository 분리:
    • TripRepositoryCustom (인터페이스): 동적 쿼리 메서드(getTripList)를 선언합니다.
    • TripRepositoryImpl (구현체): JPAQueryFactory를 주입받아 실제 동적 쿼리 로직을 구현합니다.
  3. 동적 쿼리 로직:
    • TripSearchCondition (DTO): 클라이언트로부터 받은 검색 조건(상태, 목적지, 제목)과 정렬 기준을 담는 객체입니다.
    • BooleanBuilder / where() 다중 파라미터: TripSearchCondition의 값이 null이 아닌 경우에만 where 절에 해당 조건을 추가하여 동적으로 쿼리를 생성합니다.
    • 동적 정렬: 검색 조건에 포함된 정렬 기준(e.g., endDate)에 따라 orderBy()OrderSpecifier를 사용하여 정렬 순서를 동적으로 변경합니다.

✅ 3. 프론트엔드 라우팅 및 공통 모듈 설계

  • 페이지별로 필요한 스크립트만 로드하고, 인증 상태에 따라 접근을 제어하는 프론트엔드 라우팅 시스템을 구축했습니다.
  1. 라우팅 설정 (routes-config.js):
    • 애플리케이션의 모든 경로(e.g., /dashboard, /trips)와 해당 경로에 필요한 JS 모듈, 인증 요구 여부(authRequired)를 중앙에서 설정합니다.
  2. 동적 모듈 로딩 (app.js):
    • 페이지 진입 시 현재 URL을 확인하여 routes-config.js에 정의된 JS 모듈을 동적 import()로 로드합니다.
    • 라우트 가드(Route Guard): 접속하려는 페이지가 인증을 요구(authRequired: true)하고 사용자가 로그인하지 않은 상태라면, 로그인 페이지로 리다이렉트시키는 보호 로직을 구현했습니다.
  3. 공통 유틸리티 모듈 (common.js):
    • 날짜 포맷팅, 알림창 표시, 인증 관련 함수 등 여러 페이지에서 공통으로 사용되는 유틸리티 함수들을 모듈화하여 코드의 재사용성을 높였습니다.
  4. 페이지별 스크립트 추가:
    • dashboard.js, trip-list.js 등 각 페이지의 초기화 및 이벤트 처리를 담당하는 스크립트를 추가하고, 라우팅 시스템을 통해 필요할 때만 로드되도록 구성했습니다.

✅ 4. 테스트 및 리팩토링

  • 구현된 기능의 안정성을 보장하고 코드의 품질을 개선하기 위해 테스트 코드 작성 및 리팩토링을 진행했습니다.

  • 테스트 코드 (TripRepositoryTest):

    • @SpringBootTest 어노테이션을 사용하여 통합 테스트 환경을 구축하고, QueryDSL로 구현한 동적 여행 조회 및 페이징 기능이 올바르게 동작하는지 검증했습니다.
    • 여행 상태를 변경하는 비즈니스 로직에 대한 테스트 케이스를 추가했습니다.
  • 리팩토링:

    • 메서드의 역할을 더 명확하게 나타내기 위해 findTripsByUsergetTripList로 변경했습니다.
    • Trip 엔터티에 @ToString(exclude = "user")를 추가하여 양방향 연관관계에서 발생할 수 있는 순환 참조 문제를 방지했습니다.

📌 요약

  • 백엔드에서는 Trip 엔터티를 중심으로 데이터 모델을 설계하고, QueryDSL을 도입하여 복잡한 조건의 동적 검색 및 정렬 기능을 구현했습니다.
  • 프론트엔드에서는 설정 기반의 라우팅 시스템을 구축하여 페이지별 모듈을 동적으로 로드하고, 라우트 가드를 통해 인증 기반의 접근 제어를 구현했습니다.
  • common.js와 같은 공통 모듈을 통해 코드의 재사용성을 높였으며, 통합 테스트를 통해 구현된 기능의 신뢰성을 확보했습니다.

0개의 댓글