简体   繁体   中英

How to use Querydsl to construct complex predicate that involves multiple tables?

I am trying to utilize Querydsl to fetch some results from a table. So far, this is what I have tried -

Assume there are 5 entities named T1..T5. And I am trying to do this SQL query in Querydsl -

SELECT T1.*
FROM T1,T2,T3,T4,T5
WHERE T1.A=T2.A
AND T2.B=T5.B
AND T4.C=T2.C
AND T1.B=1234;

I tried the following, but the Hibernate query keeps running, and does not seem to end.

booleanBuilder.and(JPAExpressions.select(qT1).from(qT1,qT2,qT3,qT4,qT5)
.where(
    qT1.a.eq(qT2.a)
    .and(qT1.a.eq(qT2.a))
    ... // and so on
    .exists());

I am using the Repository that extends QuerydslPredicateExecutor and using findAll to execute this. The problem is that the query takes forever to run. And I am interested only in the first result that may appear. So, where am I going wrong that is making the query execute forever?

Edit: I opted to use the JPAQuery instead. And of course, the Hibernate query generated is the same. Here is my JPAQuery.

JPQLQuery jpqlQuery = new JPAQuery(entityManager);
        jpqlQuery.select(qT1).from(qT1, qT2, qT3, qT4, qT5).where(booleanBuilder);
        return jpqlQuery.fetch();

How do I incorporate the limit in the above JPAQuery so that only the first result is fetched?

The complexity is not in the predicate or in QueryDSL, but in the fact that you're executing it in a subquery that has to be executed for every row in the result. Depending on the total result set size, this may become increasingly difficult to compute. It is however equally complex among QueryDSL, Hibernates HQL, JPA's JPQL or your databases SQL. So the SQL you're trying to generate, will be just as slow.

You might succeed at optimising the query using a limit clause. Adding a limit clause to query in QueryDSL is quite trivial: .limit(1) . So then your query becomes:

JPQLQuery jpqlQuery = new JPAQuery(entityManager);
        jpqlQuery.select(qT1).from(qT1, qT2, qT3, qT4, qT5).where(booleanBuilder);
        jpqlQuery.limit(1);
        return jpqlQuery.fetch();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM