본문 바로가기
Project/MangoPlate Clone

메인 목록에 QueryDsl 필터링 추가

by 혀눅짱 2023. 2. 17.

망고플레이트 실제 앱을 보면 생각보다 필터링할수있는 종류가 많다. 우선 주차여부와 현재 사용자 위치를 기준으로 설정한반경거리 범위에 포함되는 식당만 조회되도록 필터링을 추가했다.

 

거리반경범위 역시 지난번 거리순 소팅때 사용한 mariaDb함수를 호출하는 방식을 이용하였는데 같은 로직이기 때문에 별도의 메소드로 빼놔 재사용하도록 하였다.

private StringTemplate callStDistanceSphereFunction(MainParamDto mainParamDto){
    return Expressions.stringTemplate("ST_Distance_Sphere({0}, {1})",
            Expressions.stringTemplate("POINT({0}, {1})",
                    mainParamDto.getLongitude(),
                    mainParamDto.getLatitude()
            ),
            Expressions.stringTemplate("POINT({0}, {1})",
                    restaurant.longitude,
                    restaurant.latitude
            ));
}

그 후 동적쿼리를 위한 각 필터링조건에 필요한 메소드를 각각 만들었다.

 

private BooleanExpression filterParkingYn(MainParamDto mainParamDto){
    if(!StringUtils.hasLength(mainParamDto.getParkingYn())){
        return null;
    }
    return restaurant.parkingYn.eq(mainParamDto.getParkingYn());
}

//반경 ?km이내 필터
private BooleanExpression filterDistance(MainParamDto mainParamDto){
    if(!StringUtils.hasLength(mainParamDto.getLatitude()) || !StringUtils.hasLength(mainParamDto.getLongitude()) || !StringUtils.hasLength(mainParamDto.getDistanceLimit())){
        return null;
    }
    return callStDistanceSphereFunction(mainParamDto).loe(mainParamDto.getDistanceLimit());
}
List<Tuple> result = jpaQueryFactory.select(
                restaurant,
                MathExpressions.round(review.rating.avg(),1),
                review.rating.count()
        )
        .from(restaurant)
        .leftJoin(restaurant.reviews, review)
        .leftJoin(restaurant.category, category).fetchJoin()
        .leftJoin(restaurant.region, region).fetchJoin()
        .where(filterParkingYn(mainParamDto),filterDistance(mainParamDto))
        .groupBy(restaurant.id)
        .orderBy(filterSort(mainParamDto))
        .offset(pageable.getOffset())
        .limit(pageable.getPageSize())
        .fetch();

JPAQuery<Long> total = jpaQueryFactory.select(
            restaurant.count()
    )
        .from(restaurant)
        .where(filterParkingYn(mainParamDto),filterDistance(mainParamDto));

먼저 필터링 메소드들은 파라미터가 Null이거나 값이 없으면 그냥 null을 리턴해버린다.

이유는 해당 메소드를 호출하는곳이 쿼리의 where 절인데 만약 리턴이 Null이면 그냥 해당 조건은 무시된다. 

반경필터링역시 거리계산함수호출후 그 결과값이 파라미터의 반경범위보다 작거나 같도록 설정하였다.

loe -> 실제쿼리에서 (<=) 와 같음.

 

페이징목록을 불러오는 쿼리에 where절이 추가되었다 여기서 까먹지 말아야할 것 전체목록건수를 뽑는쿼리에도 동일한 where 절 조건을

추가해줘야한다. 그래야 페이징처리하는데 해당조건을 만족하는 토탈건수가 정확히나오니까.. 이거안하면 조건에 안맞더라도 그냥 전체 restaurant목록을 가져와버려서 페이징응답데이터가 이상하게 나감;

 

일단 메인화면 목록구성하는데 필요한 필터링과 조건이 어느정도 구색은 갖춰졌다. 클라이언트에서 잘 파싱해서 보여지길 바란다 

 

'Project > MangoPlate Clone' 카테고리의 다른 글

JPA Auditing 설정  (0) 2023.02.24
간단한 logBack 설정  (0) 2023.02.20
QueryDSL에서 mariaDB 위도 경도 계산 함수 호출  (0) 2023.02.15
공통컴포넌트 및 유틸  (0) 2023.02.14
JPA Setting 및 Test  (0) 2023.02.14