메서드로 안하고 Querydsl 사용! 이번에는 확장 구현체를 만드는 방법을 사용해 볼 것
public class StudyRepositoryExtensionImpl extends QuerydslRepositorySupport implements StudyRepositoryExtension
StudyRepositoryExtensionImpl 에서 Extension 부분은 마음대로 설정해도 되지만, 이 인터페이스를 구현한 구현체를 만들 때는 반드시 Impl 을 붙여줘야 한다.
Querydsl 로 구현을 할 것인데, 이때 사용할 수 있는 도우미 클래스로 QuerydslRepositorySupport 가 있다. 이때 컴파일 에러가 발생한다! 😱😱
Q. 왜?
public StudyRepositoryExtensionImpl() {
super(Study.class);
}
Q. 생성자를 만들어주면 해결, 왜 생성자를 만들어줬을까?
- repository는 @Transactional(readOnly = true) 기본은 readOnly
- service는 @Transactional 붙이고 readOnly 없이
조회는 주로 repository 통해서 하기로 함! 이제 본격적으로 Querydsl 를 사용하면 되는데 이전 처럼 Predicate 를 사용하지 않고, from 으로 시작할 수 있다.
비어있는 lists라서 사이즈로 비교하면 가능했는데, 왜 안되는지 ...? -> 이해할 수 없는 상황
타임리프가 제공하는 lists 라는 기능이 있다. #lists.isEmpty(studyList)
select
study0_.id as id1_7_,
study0_.closed as closed2_7_,
study0_.closed_date_time as closed_d3_7_,
study0_.full_description as full_des4_7_,
study0_.image as image5_7_,
study0_.path as path6_7_,
study0_.published as publishe7_7_,
study0_.published_date_time as publishe8_7_,
study0_.recruiting as recruiti9_7_,
study0_.recruiting_updated_date_time as recruit10_7_,
study0_.short_description as short_d11_7_,
study0_.title as title12_7_,
study0_.use_banner as use_ban13_7_
from
study study0_
where
study0_.published=?
and (
lower(study0_.title) like ? escape '!'
)
or exists (
select
1
from
study_tags tags1_,
tag tag2_
where
study0_.id=tags1_.study_id
and tags1_.tags_id=tag2_.id
and (
lower(tag2_.title) like ? escape '!'
)
)
or exists (
select
1
from
study_zones zones3_,
zone zone4_
where
study0_.id=zones3_.study_id
and zones3_.zones_id=zone4_.id
and (
lower(zone4_.local_name_of_city) like ? escape '!'
)
)
db 에다가 실행해 볼 수 있다. 그대로!
검색 창에 jpa를 검색했다고 하자. 이때 나오는 스터디 개수를 3개라고 했을 때 스터디 한번 조회하고, 스터디 당 태그, 존, 멤버/ 태그 존, 멤버/ 태그 존, 멤버가 3개씩 발생한다. 이는 n+1 select 문제이다. 여태까지는 이를 해결하기 위해 엔티티 그래프를 사용했다. 하지만 지금 Querydsl 을 사용하고 있으므로 패치할 내용도 쿼리해서 사용해야 한다.
출처 : 인프런 백기선님의 스프링과 JPA 기반 웹 애플리케이션 개발