본문 바로가기

Spring/JPA

7) QueryDsl InlineView(인라인뷰) 해결하기.

반응형

결론부터 애기를 하자면 QueryDsl로 인라인뷰는 쿼리를 현재는 구현 할 수 없다.

 

그럼 어떻게 인라인뷰쿼리의 효과를 만들어 낼까를 고민해 보자. 아래 간단한 인라인뷰 쿼리가 있다.

select * from Product p ,
 (
 	select sp.name from Product sp group by sp.name
 ) mp 
 where p.name = mp.name

위와 같은 쿼리는 사실 간단히 인라인뷰를 사용하지  않고 조건절에 넣어서 해결이 된다.

select * from Product p 
 where p.name in (
 	(
 		select sp.name from Product sp group by sp.name 
 	)

이 쿼리를 간단하게 QueryDsl로 바꿔 보자.

query.selectFrom(p)
	.where(
    	p.name.in(
          JPAExpressions.select(p.name)
          .from(p).groupBy(p.name)
        )
    ).fetch()

위와 같이 간단하게 해결이 가능하다. 

 

그럼 아래와 같은 쿼리는 어떻게 해결을 할지 고민해 보자.

select p.* from Product p ,
 (
 	select sp.name as name , max(sp.number) as pnumber from Product sp group by sp.name
 ) mp 
 where p.name = mp.name and p.number = mp.pnumber

위와 같은 쿼리는 사실 굉장히 많이 다양한 이유로 사용 될 수있는 쿼리이다. 

이것을 어떻게 바꿀수 있을까 고민하다. 쿼리를 아래와같이 변경 할 수 있다는것을 알게 되었다.

select p.* from Product p 
where (p.name , p.number) in (
	select sp.name as name , max(sp.number) as pnumber from Product sp group by sp.name
)

두개 이상의 컬럼을 묶어서 사용할수 있다는것을 알게 되었다.

이제 이것을 어떻게 QueryDsl 로 변환을 할 지 생각해 보자.

query.selectFrom(p)
	.where(
    	Expressions.list(p.name , p.number).in(
          JPAExpressions.select(p.name , p.number.max())
          .from(p).groupBy(p.name)
        )
    ).fetch()

위와 같이 Expressions.list 를 이용해서 해결 할수 있게 되었다.