
Question:
How to write JPA query in Spring Data that uses at least one of three parameters?
I have these three parameters:
<ol><li>Id (PK)</li> <li>Name</li> <li>Surname</li> </ol>Client must supply at least one of these three parameters and I want to find user by these not-empty parameters.
Is it possible to create such custom query to my repository or do I have to create custom queries for all possible combination of WHERE
conditions?
You can have your repository extend org.springframework.data.querydsl.QueryDslPredicateExecutor and use the inherited findAll(Predicate predicate) method to query using any combination of parameters.
You would not then have to write any query methods:
<a href="http://docs.spring.io/spring-data/jpa/docs/1.10.5.RELEASE/reference/html/#core.extensions.querydsl" rel="nofollow">http://docs.spring.io/spring-data/jpa/docs/1.10.5.RELEASE/reference/html/#core.extensions.querydsl</a>
You can also have the Predicate automatically bound in a Spring MVC Controller as detailed here:
<a href="https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling#querydsl-web-support" rel="nofollow">https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling#querydsl-web-support</a>
and here:
<a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.web.type-safe" rel="nofollow">https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.web.type-safe</a>
So your controller can then automatically handle a search with 1,2 or all 3 parameters passed as request parameters without your having to write any code at all.
Answer2:This is where you need the ability to create dynamic queries at runtime.
In your application code, you should have logic to build the predicate based on whether each of the above properties from the input DTO is empty or not.
One way to do it is to use QueryDSL. To use QueryDSL, you should include the relevant dependency in your pom/gradle file and then your repository should extend the QueryDslPredicateExecutor interface. This will give you two additional generic finder methods.
T findAll(Predicate) or
Page<T> findAll(Predicate, Pageable)
One thing to keep in mind is that the above two methods are appropriate where this is no need to do a join
Your requirement here seems to be a single table query, so either one of the finder methods should suffice.
If you do need to do a join with other tables and need fine grained control over how the JOIN happens (INNER JOIN vs LEFT OUTER JOIN vs CROSS JOIN) etc, then you should consider creating a Custom repository that your repository can extend. And then provide your own customImpl that you can now access from the repository.
Answer3:thanks a lot for the reply ... as i read Spring is not easy flexible as other framework... for i.e i tried some node js api framework and it is easier and more flexible .. what do you think about this ?