1. 의존성 주입
QueryDsl EntityManager 를 전역으로 의존성을 주입해주기 위해 다음을 만들어준다.
@Configuration
public class QueryDslConfig {
@PersistenceContext
private EntityManager entityManager;
@Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
그 다음 Repository에서 다음과 같이 깔끔하게 해줄 수 있다.
@Repository
@RequiredArgsConstructor
public class PostCustomRepositoryImpl implements PostCustomRepository {
private final JPAQueryFactory jpaQueryFactory;
2. 2번 이상의 Depth로 JoinFetch 할 경우
JPQL 같은 경우는 Join Fetch를 여러번 타고 갈 때
select u from User u join fetch u.team t join fetch t.site
이런 식으로 가지만, QueryDsl 같은 경우는
query
.selectFrom(user)
.leftJoin(user.team, team)
.leftJoin(team.site, site)
이런식으로 타고가야 한다.
3. 같은 객체를 2번 사용할 경우 ( 같은 query 내에 같은 객체를 다른 곳에서도 Join 할 경우 )
var a = new QUser("testUser");
var b = new QUser("sequenceUser");
이런 식으로 Q객체를 변수로 할당하여 사용하면 된다.
4. 메소드화
public JPAQuery<User> findUser() {
return query
.selectFrom(user)
.leftJoin(user.team, team)
.leftJoin(team.site, site);
}
이런 식으로 Query 메소드를 분리할 수도 있다.
5. Optional 사용
public Optional<JPAQuery<User>> findUser() {
return Optional.ofNullable(query
.selectFrom(user)
.leftJoin(user.team, team)
.leftJoin(team.site, site)
.fetchFirst());
}
Optinal 을 사용하여 아래와 같이 NoSuchElementException을 던질 수도 있다.
public User findLatestOne() {
return findUser().orElseThrow();
}
6. Optional 사용 2
fetch종류에 따라 메소드를 분할 할 경우 아래와 같이 사용 할 수 도 있다.
public JPAQuery<User> findUser() {
return query
.selectFrom(user)
.leftJoin(user.team, team)
.leftJoin(team.site, site)
.fetchFirst();
}
public User findLatestOne() {
return Optional.ofNullable(findUser().fetchFirst()).orElseThrow();
}
public List<User> findUsers() {
return findUser().fetch();
}