boolean existsByName(String name);
Spring Data Jpa 에선 메서드로 쿼리를 만들어서 사용한다.
하지만 조금이라도 복잡해진다면 메서드로 표현이 힘들때가 있다.
- 예약하고 싶은 기간에 이미 숙소가 예약중인지 확인하는 쿼리
- 메서드로만 표현하기엔 너무 길어지고 복잡하다.
이런 경우 @Query
를 사용하지만 JPQL에선 select의 exists 를 지원하지 않는다.
하지만 where절에서는 가능하기에 count쿼리로 우회하여 사용한다.
- 하지만 이 방식은 성능상 문제가 있다.
count VS exists
exists
의 경우 첫번째 결과에서 바로 true를 리턴하여 빠르다.- 하지만
count
의 경우 결국 총 몇건인지 확인해야하기 때문에 전체를 확인할 수 밖에 없어exists
보다 느리다.
QueryDsl에서의 exists
- 블로그에선 QueryDsl이 기본적으로 count 쿼리 방식을 사용했다고 하였지만 버전이 업그레이드됨에 따라 limit 쿼리 방식으로 변경된 것 같다.
QuerydslJpaPredicateExecutor.exists
- 사용해보려 했지만 실패…. 후에 공부한 뒤 다시 봐야겠다.
limit 1
를 통해 1개만 조회하여 있는 지 없는 지 판단
@Override
public boolean existReservationByRoom(Room room, Long reservationId, ReservationDate reservationDate) {
LocalDate checkIn = reservationDate.getCheckIn();
LocalDate checkOut = reservationDate.getCheckOut();
Integer fetchOne = queryFactory.selectOne()
.from(reservation)
.where(
eqRoom(room)
, notEqReservationId(reservationId)
, notInCanceled() // 상태가 취소가 아닌 것
, betweenCheckIn(checkIn, checkOut).or(betweenCheckOut(checkIn, checkOut))
)
.fetchFirst(); // limit 1
return fetchOne != null;
}
결론
- 오버엔지니어링일 수 도 있겠지만 좋은 방식이 있는 데 그것을 따라가지 않을 이유가 없어서 구현해보았다.
- 데이터가 많지 않아 크게 체감되지 않지만 좀 더 안정적인 프로그램이 되지 않았나 생각한다!
Reference
'Back-End > Spring' 카테고리의 다른 글
JPA Fetch Join MultipleBagFetchException (0) | 2022.08.20 |
---|---|
ObjectMapper 제너릭 타입 (0) | 2022.07.29 |
댓글