Customizing Param Binding for QueryDSL Support

不问归期 提交于 2019-11-29 12:02:32

There are two ways that you can accomplish this using Java 7. The first way is to create a generic base repository that will apply the custom bindings to all of the implemented model repositories. For example:

public class GenericModelRepository<T, ID extends Serializable, S extends EntityPath<T>> extends QueryDslJpaRepository<T, ID> 
    implements QuerydslBinderCustomizer<S> {

    public GenericModelRepository(
            JpaEntityInformation<T, ID> entityInformation,
            EntityManager entityManager) {
        super(entityInformation, entityManager);
    }

    public GenericModelRepository(
            JpaEntityInformation<T, ID> entityInformation,
            EntityManager entityManager,
            EntityPathResolver resolver) {
        super(entityInformation, entityManager, resolver);
    }

    @Override 
    public void customize(QuerydslBindings bindings, S t) {
            bindings.bind(String.class).first(new SingleValueBinding<StringPath, String>() {
                @Override 
                public Predicate bind(StringPath path, String s) {
                    return path.equalsIgnoreCase(s);
                }
            });
    }
}

To tell Spring Data to use this base repository when implementing all of your custom repository interfaces, simply add it as the repositoryBaseClass in the @EnableJpaRepositories annotation:

@Configuration
@EnableJpaRepositories(basePackages = { "me.woemler.project.repositories" }, 
        repositoryBaseClass = GenericModelRepository.class)
@EnableTransactionManagement
public class RepositoryConfig { ... }


@RepositoryRestResource
public interface PersonRepository extends JpaRepository<Person, Long>, 
        QueryDslPredicateExecutor<Person>,
        QuerydslBinderCustomizer<EntityPath<Person>> {
}

Now all web service StringPath query operations will be case-insensitive equality tests:

GET http://localhost:8080/persons?name=joe%20smith


"_embedded": {
    "persons": [
      {
        "name": "Joe Smith",
        "gender": "M",
        "age": 35,
        "_links": {
          "self": {
            "href": "http://localhost:8080/persons/1"
          },
          "person": {
            "href": "http://localhost:8080/persons/1"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/persons"
    },
    "profile": {
      "href": "http://localhost:8080/profile/persons"
    }
  },
  "page": {
    "size": 20,
    "totalElements": 1,
    "totalPages": 1,
    "number": 0
  }
}

The second option, should you want more fine control over how each repository handling its bindings would be to create an Impl version of the repositories you wish to customize:

public class PersonRepositoryImpl implements QuerydslBinderCustomizer<EntityPath<Person>> {
    @Override
    public void customize(QuerydslBindings bindings, EntityPath<Person> t) {
        bindings.bind(String.class).first(new SingleValueBinding<StringPath, String>() {
            @Override
            public Predicate bind(StringPath path, String s) {
                return path.equalsIgnoreCase(s);
            }
        });
    }
}

You can then use the @EnableJpaRepositories annotation normally, but you must create an Impl instance for each of your repository interfaces that you wish to customize.

you can use the

BooleanBuilder
import com.mysema.query.BooleanBuilder;

to construct the queryDsl predicate

QUser quser=QUser.User;
BooleanBuilder whereClause=new BooleanBuilder();
whereClause.and(quser.property1.eq("some"));
whereClause.and(quser.property2.in(listOfValues));

springRepository.find(whereClause);

FootNote: java 8 would help reduce a lot of keystrokes for the above case

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!