오늘은 서비스를 진행하면서 어떤 엔티티에 대한 개수를 조회해야하는 기능을 구현하면서 공부한 내용을 기록한다!
먼저 구현하려는 내용을 알아보자!
사실 상 가장 쉬운 방법이다.
방법이 총 2개가 존재한다.
조회를 하고, return 되는 List의 size를 구하면 되는 것이다.
하지만 해당 방법은 조회를 Entity 그 자체를 하는 것이 된다.
성능상 좋지 못하다.(엔티티의 개수가 증가할 수록 성능 Bad)
CountBy 함수를 사용한다.
이 방법을 쓰면 실제 Query에서의 "Count(-)" 함수를 쓰는 것이다. 그럼 사용해보자.
// 파라미터의 시간보다 "StartAppointmentDate"가 뒤에 있는것 조회
Long countByStartAppointmentDateAfter(LocalDateTime date);
이렇게 했을 때 생성되는 query를 살펴보자.
정상적으로 가능!
But..
이제 전체 인원 > 참여 인원인 부분을 조건 절로 추가해야 한다.
그래서 생각한 메서드이름
Long countByStartAppointmentDateAfterAndLimitPeopleCountGreaterThanParticipantCount(LocalDateTime date);
너무 길긴 하지만.. 프로젝트 빌드가 안된다.
이유는?
GreaterThan 다음에 ParticipantCount가 있으면 안된다. 파라미터로 들어와야 하는 것이다.
맞다. 엔티티 내의 값들은 계산할 수가 없는 것이다.....
(방법을 찾아보았지만.. 모르겠다)
room Entity 내의 값들을 비교해서 조회하는 방법좀 알려듀세요.. 키워드라두..
그럼 QueryDsl에 지원해주는게 있을까? 찾아보았다.
다음 사진을 보면
더이상 fetchCount() 함수가 사용되지 않는다고 한다.
부족한 실력으로 번역을 해봤더니, QueryDsl로 여러가지의 조건 때문에 (having 절과 같은) count를 구체적으로 반영할 수 없다고 한다. 그래서 실행되는 내용이 단순 조회 후 size() 연산과 같다고 한다.
결국 단순 JPA를 이용하는 것과 똑같다.
여러가지 자료를 찾아보았을 때, 많은 사람들이 JPQL을 직접 사용하더라. 자료 시간을 보니 다 최신이다.
직접 Query를 작성하고 Repository에 추가하자!
@Query("SELECT COUNT(*) FROM Room a WHERE DATE(Now()) < DATE(a.startAppointmentDate) AND a.limitPeopleCount > a.participantCount")
Long getAvailableRoomCount();
해당 방법이 가장 주된 방법인 듯 하다.
근데 Query를 개발자가 직접 써둔 것이 너무나 마음에 걸린다.
꼭꼭 JPA의 2번으로 성공시켜보자.(이름 줄이는 방법도..)
이건 단순한 궁금증이다. 뭐가 더 빠를까? 싶어서 초를 세보았다.
둘 다 29ms가 나온다.
때때로 다르지만 10~50 사이로 나온다.
사실상 차이가 없지 않은가?
하지만 개발적으로 보았을 때 뭐가 좋을까?
내가 느끼고 아는대로 써보자면 장단점이 다음과 같다.
이 두가지 방법중 뭐가 좋은지는 나도 잘 모르겠다.
나중에 이런 결정을 내리는 순간이 올 것 같은데, 그때의 회사 시니어 분들께 물어봐야지~~~