Skip to content

Commit

Permalink
#23 [Fix] DTO로 쿼리를 처리
Browse files Browse the repository at this point in the history
DTO 추가 및 기존 DTO 수정
  • Loading branch information
JSoi committed Jul 14, 2022
1 parent 154585f commit e31667f
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import java.util.List;

import static com.mpnp.baechelin.config.QuerydslConfig.locationBuilder;
import static com.mpnp.baechelin.review.domain.QReview.review1;
import static com.mpnp.baechelin.review.domain.QReview.review;
import static com.mpnp.baechelin.store.domain.QStore.store;

@Repository
Expand All @@ -31,11 +31,12 @@ public List<Review> findRecentReviews(BigDecimal latStart,
int limit) {
BooleanBuilder builder = locationBuilder(latStart, latEnd, lngStart, lngEnd);
// 위도 경도에 해당하는 가게를 찾음 -> 해당 댓글을 다 가져옴 -> 내림차순 정렬 -> limit
return queryFactory.selectFrom(review1)
.innerJoin(review1.storeId, store)
.on(review1.storeId.id.eq(store.id))
// TODO 쿼리문 개선하기
return queryFactory.selectFrom(review)
.innerJoin(review.storeId, store)
.on(review.storeId.id.eq(store.id))
.where(builder)
.orderBy(review1.createdAt.desc())
.orderBy(review.createdAt.desc())
.limit(limit)
.fetch();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,22 @@ public List<StoreResponseDto> getStoreInRange(@RequestParam(required = false) Bi
}

@GetMapping("/point")
public List<StoreResponseDto> getStoreInRangeHighPoint(@RequestParam(required = false) BigDecimal latStart,
@RequestParam(required = false) BigDecimal latEnd,
@RequestParam(required = false) BigDecimal lngStart,
@RequestParam(required = false) BigDecimal lngEnd,
public List<StoreResponseDto> getStoreInRangeHighPoint(@RequestParam(required = false) BigDecimal lat,
@RequestParam(required = false) BigDecimal lng,
@RequestParam(required = false) String category,
@RequestParam(required = false) List<String> facility,
@PageableDefault Pageable pageable) {
List<Store> betweenLngLat = storeQueryRepository.findStoreOrderByPoint(latStart, latEnd, lngStart, lngEnd, category, facility, pageable);
List<Store> betweenLngLat = storeQueryRepository.findStoreOrderByPoint(lat, lng, category, facility, pageable);
return betweenLngLat.parallelStream().map(storeService::storeToResDto).collect(Collectors.toList());// 순서보장
}

@GetMapping("/bookmark")
public List<StoreResponseDto> getStoreInRangeHighBookmark(@RequestParam(required = false) BigDecimal latStart,
@RequestParam(required = false) BigDecimal latEnd,
@RequestParam(required = false) BigDecimal lngStart,
@RequestParam(required = false) BigDecimal lngEnd,
public List<StoreResponseDto> getStoreInRangeHighBookmark(@RequestParam(required = false) BigDecimal lat,
@RequestParam(required = false) BigDecimal lng,
@RequestParam(required = false) String category,
@RequestParam(required = false) List<String> facility,
@RequestParam int limit) {
List<Store> betweenLngLat = storeQueryRepository.findStoreOrderByBookmark(latStart, latEnd, lngStart, lngEnd, category, facility, limit);
List<Store> betweenLngLat = storeQueryRepository.findStoreOrderByBookmark(lat, lng, category, facility, limit);
return betweenLngLat.parallelStream().map(storeService::storeToResDto).collect(Collectors.toList());// 순서보장
}
}
69 changes: 69 additions & 0 deletions src/main/java/com/mpnp/baechelin/store/dto/StoreCardDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.mpnp.baechelin.store.dto;

import com.mpnp.baechelin.review.domain.Review;
import com.mpnp.baechelin.review.dto.ReviewImageResponseDto;
import com.mpnp.baechelin.review.dto.ReviewResponseDto;
import com.mpnp.baechelin.store.domain.Store;
import com.mpnp.baechelin.user.domain.User;
import lombok.*;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PACKAGE)
@Getter
@Setter
@Builder
@Slf4j
public class StoreCardDto implements Comparable<StoreCardDto> {
private int storeId;
private String category;
private String name;
private BigDecimal latitude;
private BigDecimal longitude;
private String address;
private String elevator;
private String toilet;
private String parking;
private String phoneNumber;
private String heightDifferent;
private String approach;
private List<StoreImgResponseDto> storeImgList;
private boolean bookmark;

@Builder.Default
private double pointAvg = 0.0;

@Override
public int compareTo(StoreCardDto sad) {
if (this.pointAvg > sad.pointAvg) {
return 1;
} else if (this.pointAvg < sad.pointAvg) {
return -1;
}
return 0;
}


public StoreCardDto(Store store, User user) {
this.storeId = store.getId();
this.category = store.getCategory();
this.name = store.getName();
this.latitude = store.getLatitude();
this.longitude = store.getLongitude();
this.address = store.getAddress();
this.elevator = store.getElevator();
this.toilet = store.getToilet();
this.parking = store.getParking();
this.phoneNumber = store.getPhoneNumber();
this.heightDifferent = store.getHeightDifferent();
this.approach = store.getApproach();
this.storeImgList = store.getStoreImageList().parallelStream().map(StoreImgResponseDto::new).collect(Collectors.toList());
this.pointAvg =Double.parseDouble(String.format(store.getReviewList().stream()
.collect(Collectors.averagingDouble(Review::getPoint)).toString(), 0.1f));
this.bookmark = true;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.mpnp.baechelin.store.dto;

import com.mpnp.baechelin.store.domain.StoreImage;
import lombok.Getter;

@Getter
public class StoreImgResponseDto {
private String storeImageUrl;

public StoreImgResponseDto(StoreImage storeImage){
this.storeImageUrl = storeImage.getStoreImageUrl();
}
public StoreImgResponseDto(String storeImageUrl) {
this.storeImageUrl = storeImageUrl;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
package com.mpnp.baechelin.store.repository;

import com.mpnp.baechelin.config.QuerydslConfig;
import com.mpnp.baechelin.store.domain.Store;
import com.mpnp.baechelin.store.dto.StoreResponseDto;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.StringPath;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
import org.springframework.stereotype.Repository;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.stream.Collectors;

import static com.mpnp.baechelin.config.QuerydslConfig.locationBuilder;
import static com.mpnp.baechelin.store.domain.QStore.store;

@Repository
@Transactional
@Slf4j
public class StoreQueryRepository extends QuerydslRepositorySupport {
private final JPAQueryFactory queryFactory;

Expand All @@ -37,52 +41,70 @@ public List<Store> findBetweenLngLat(BigDecimal latStart,
Pageable pageable) {

BooleanBuilder builder = locAndConditions(latStart, latEnd, lngStart, lngEnd, category, facility);

return queryFactory.selectFrom(store)
BigDecimal nowLat = (latStart.add(latEnd)).divide(new BigDecimal("2"), 22, RoundingMode.HALF_UP);
BigDecimal nowLng = (lngStart.add(lngEnd)).divide(new BigDecimal("2"), 22, RoundingMode.HALF_UP);
List<Store> storeResultList = queryFactory.selectFrom(store)
.where(builder)
.limit(pageable.getPageSize())
.offset(pageable.getOffset())
.fetch();
// 가까운순으로 정렬하기
storeResultList.sort((thisStore, newStore) -> {
BigDecimal thisDiff = nowLat.subtract(thisStore.getLatitude()).abs().add(nowLng.subtract(thisStore.getLongitude()).abs());
BigDecimal newDiff = nowLat.subtract(newStore.getLatitude()).abs().add(nowLng.subtract(newStore.getLongitude()).abs());
return thisDiff.compareTo(newDiff);
});
// 총 페이지 개수 * 시작 페이지 = 시작 페이지
getStorePaged(storeResultList, pageable);
return storeResultList;
// 업데이트 쿼리
// return queryFactory.selectFrom(store)
// .where(builder)
// .limit(pageable.getPageSize())
// .offset(pageable.getOffset())
// .fetch();
}

//TODO 별점순
public List<Store> findStoreOrderByPoint(BigDecimal latStart,
BigDecimal latEnd,
BigDecimal lngStart,
BigDecimal lngEnd,
//TODO 별점순 - 쿼리 결과로 산출된 리스트의 평균 구하기, 정렬, 페이징
public List<Store> findStoreOrderByPoint(BigDecimal lat,
BigDecimal lng,
String category,
List<String> facility,
Pageable pageable) {


BooleanBuilder builder = locAndConditions(latStart, latEnd, lngStart, lngEnd, category, facility);
BooleanBuilder builder = locTwoPointAndConditions(lat, lng, category, facility);

return queryFactory.selectFrom(store)
List<Store> resultList = queryFactory.selectFrom(store)
.where(builder)
.limit(pageable.getPageSize())
.offset(pageable.getOffset())
.orderBy(store.pointAvg.desc())
.fetch();

List<StoreResponseDto> resultAvgList = resultList.stream().sorted()
.map(StoreResponseDto::new).collect(Collectors.toList());

getStorePaged(resultAvgList, pageable);


// return queryFactory.selectFrom(store)
// .where(builder)
// .limit(pageable.getPageSize())
// .offset(pageable.getOffset())
// .orderBy(store.pointAvg.desc())
// .fetch();
}

//TODO 북마크순
public List<Store> findStoreOrderByBookmark(BigDecimal latStart,
BigDecimal latEnd,
BigDecimal lngStart,
BigDecimal lngEnd,
public List<Store> findStoreOrderByBookmark(BigDecimal lat,
BigDecimal lng,
String category,
List<String> facility,
int limit) {

BooleanBuilder builder = locAndConditions(latStart, latEnd, lngStart, lngEnd, category, facility);

BooleanBuilder builder = locTwoPointAndConditions(lat, lng, category, facility);

return queryFactory.selectFrom(store)
.where(builder)
.orderBy(store.bookMarkCount.desc())
.limit(limit)
.fetch();

}

private BooleanExpression facilityTF(String facility) {
Expand All @@ -99,12 +121,27 @@ private StringPath givePath(String dbFacility) {
return store.parking;
if (dbFacility.equals("approach"))
return store.approach;
else
if (dbFacility.equals("toilet"))
return store.toilet;
throw new IllegalArgumentException("배리어 프리 태그를 확인해주세요");
}

private BooleanBuilder locAndConditions(BigDecimal latStart, BigDecimal latEnd, BigDecimal lngStart, BigDecimal lngEnd, String category, List<String> facility) {
BooleanBuilder builder = locationBuilder(latStart, latEnd, lngStart, lngEnd);
return getBooleanBuilder(category, facility, builder);
}


private BooleanBuilder locTwoPointAndConditions(BigDecimal latitude, BigDecimal longitude, String category, List<String> facility) {
BooleanBuilder builder = new BooleanBuilder();
if (latitude != null && longitude != null) {
BigDecimal[] location = getRange(latitude, longitude, 20);
builder = locationBuilder(location[0], location[1], location[2], location[3]);
}
return getBooleanBuilder(category, facility, builder);
}

private BooleanBuilder getBooleanBuilder(String category, List<String> facility, BooleanBuilder builder) {
builder.and(category == null ? null : store.category.eq(category));
if (facility != null && facility.size() > 0) {
for (String fac : facility) {
Expand All @@ -113,4 +150,26 @@ private BooleanBuilder locAndConditions(BigDecimal latStart, BigDecimal latEnd,
}
return builder;
}

private BigDecimal[] getRange(BigDecimal lat, BigDecimal lng, int km) {
// km->lat,lng로 변환하기
final BigDecimal latitude = BigDecimal.valueOf(km / 110.569); // 반경
final BigDecimal longitude = BigDecimal.valueOf(km / 111.322);
// 남서, 북동으로 받아오기
// start lat-lng, end lat-lng으로 Array 받아오기
return new BigDecimal[]{lat.subtract(latitude), lat.add(latitude),
lng.subtract(longitude), lng.add(longitude)};
}

private void getStorePaged(List<?> storeResultList, Pageable pageable) {
int pageStartIndex = Long.valueOf(storeResultList.size() / pageable.getPageSize() * pageable.getOffset()).intValue();

// index 처리하기
int start = 0, end = storeResultList.size();
start = Math.max(start, pageStartIndex);
end = Math.min(end, pageStartIndex + pageable.getPageSize() - 1);

storeResultList = storeResultList.subList(start, end);
}

}

0 comments on commit e31667f

Please sign in to comment.