简体   繁体   中英

How to add a comparator to querydsl Predicate?

I have the following webservice the automatically translates get parameter queries to database selects:

public interface PersonRepo extends
        JpaRepository<Person, Long>,
        QuerydslPredicateExecutor<Person> {

}

@GetMapping
public ResponseEntity getFiltered(
    @QuerydslPredicate(root = Person.class) Predicate predicate, Pageable pageable) {
       return ResponseEntity.ok(personRepo.findAll(predicate, pageable)));
    )
}

The following queries could eg be executed:

GET /people?name=John&age=18
GET /people?name=John&age=18&page=1&sort=name,desc

Problem: I want to apply comparator queries as follows:

GET /people?name=John&age>18
GET /people?name=John&age>18&age<30
GET /people?name=John&age<30

Question: how could I achieve this? At least the later queries don't work.

I found a solution by defining a placeholder for the field, and using a QuerydslBinderCustomizer :

public interface PersonRepo extends
        JpaRepository<Person, Long>,
        QuerydslPredicateExecutor<Person>,
        QuerydslBinderCustomizer<Person> {
    default void customize(final QuerydslBindings bindings, final QPerson person) {
        bindings.bind(cache.ageMin).first((path, value) -> person.age.goe(value));
        bindings.bind(cache.ageMax).first((path, value) -> person.age.loe(value));
    }
}

Of course the age fields then have to exist as transient fields, so that querydsl knows them:

@Entity
class Person {
    @Transient
    @QueryType(PropertyType.NUMERIC)
    public int ageMin;

    @Transient
    @QueryType(PropertyType.NUMERIC)
    private int ageMax;
}

You could use a single binding and use expressions from Query DSL value operators .

public interface PersonRepo extends
    JpaRepository<Person, Long>,
    QuerydslPredicateExecutor<Person>,
    QuerydslBinderCustomizer<Person> {
    default void customize(final QuerydslBindings bindings, final QPerson person) {
        bindings.bind(cache.age).all((path, values) -> ExpressionProviderFactory.getPredicate(path, values));
    }
}

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