-
(QueryDSL) 현재 날짜와 비교(between)DB/JPA 2021. 3. 3. 13:23
(이전에 작성했던 글은 진짜 메모장이었어서 다시 정리해봅니다.)
DB에 시작일과 종료일이 있고, 현재날짜와 비교해서 아직 유효한 권한만 가져오고 싶은 경우가 있다고 가정하자.
1. JPARepository 활용시
service 단에서 현재 날짜를 보낸 뒤, repository에서 활용하는 방법
Service.java
@Service @RequiredArgsConstructor public class Service{ private final AuthRepository repository; public List<Auth> getAuthListByDate(){ return repository.findByStartDateLessThanEqualAndEndDateGreaterThanEqual(new Date(), new Date()); } }
AuthRepository
@Repository public interface AuthRepository extends JpaRepository<Auth, Long>{ // startDate <= compareWithStartDate // endDate >= compareWithEndDate public List<Auth> findByStartDateLessThanEqualAndEndDateGreaterThanEqual(Date compareWithStartDate, Date compareWithEndDate); }
2. QueryDsl 활용시
아래에서 QAuth가 뭐지...? 하시는 분들은 QueryDsl의 개념에 대해 먼저 공부하고 오시는 것을 추천드립니다.
@RequiredArgsConstructor @Repository public class QueryDslCustom{ private final JPAQueryFactory jpaQueryFactory; QAuth auth = QAuth.auth; public List<Auth> getAuthByDate(){ return jpaQueryFactory .selectFrom(auth) .where(Expressions.currentTimestamp().between(auth.starDate, auth.endDate)); } }
BUT, 위와 같은 예제로 실행할 경우 현재시각에 시분초까지 들어가기 때문에 시작일과 종료일 기준으로 명확히 계산되지 않는다.
예를 들어 현재일시가 8월 12일 오후 3시인 경우에, startDate = 2021.08.10 endDate = 2021.08.12 일 때
날짜 비교시에
- 21.08.12 15:00:00(현재) >= 21.08.10 00:00:00(시작일) 은 성립하지만,
- 21.08.12 15:00:00(현재) <= 21.08.12 00:00:00 은 성립하지 않는다.
때문에 종료일자에 대한 비교가 제대로 이루어지지 않는다.
해결법은? 시간을 제외하고 비교해야 한다.
QueryDsl을 주로 써서 JpaRepository에 대한 해결법은 아직 모르겠다..
native query를 사용하지 않는 이외에도 찾아보면 좋은 해결방법이 있을 듯 하다.
QueryDsl 사용한 해결법 (native query 사용)
.... .where(Expressions.dateTimeTemplate(LocalDateTime.class,"CONVERT(varchar(10),{0},120)",Expressions.currentTimestamp()) .between( Expressions.dateTimeTemplate(LocalDateTime.class,"CONVERT(varchar(10),{0},120)",auth.startDate), Expressions.dateTimeTemplate(LocalDateTime.class,"CONVERT(varchar(10),{0},120)",auth.endDate) )) ...
'DB > JPA' 카테고리의 다른 글
[JPA] 조회 결과 (select result) map으로 받기 (0) 2021.01.06