自定义用于QueryDSL支持的参数绑定

时间:2016-11-02 15:46:33

标签: spring-data spring-data-rest

我有一个Spring Data Rest存储库,它使用了此处概述的QueryDSL支持:

https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling#spring-data-rest

默认是使用equals查询所有指定的参数。在同一篇文章中给出了一种覆盖param绑定到equals以外的东西的机制,但它需要Java 8。

https://spring.io/blog/2015/09/04/what-s-new-in-spring-data-release-gosling#querydsl-web-support

Java 7中是否有任何干净的方法来实现相同的功能?

更新

我可以按照以下方式进行绑定自定义:

@Override
public void customize(QuerydslBindings bindings, QMember member) {
    bindings.bind(member.forename).first(new SingleValueBinding<StringPath, String>() {
        @Override
        public Predicate bind(StringPath path, String value) {
            return path.like(value);
        }
    });

    bindings.bind(member.surname).first(new SingleValueBinding<StringPath, String>() {
        @Override
        public Predicate bind(StringPath path, String value) {
            return path.startsWith(value);
        }
    });
}

但是,这些示例都在存储库接口上使用Java 8默认方法来应用它们。

public interface MemberRepository extends JpaRepository<Member, Long>, 
         QueryDslPredicateExecutor<Member>,QuerydslBinderCustomizer<QMember> {

    default void customize(QuerydslBindings bindings, QMember member) {
      ....
    }
}

在Java 7中,这显然是不可能的。我尝试使用自定义存储库但是失败并出现错误:

org.springframework.data.mapping.PropertyReferenceException:找不到类型为Member的属性自定义!

public interface MemberRepositoryCustom {

    public void customize(QuerydslBindings bindings, QMember member);
}

public class MemberRepositoryCustomImpl implements MemberRepositoryCustom {

    @Override
    public void customize(QuerydslBindings bindings, QMember member) {
        bindings.bind(member.forename).first(new SingleValueBinding<StringPath, String>() {
            @Override
            public Predicate bind(StringPath path, String value) {
                return path.like(value);
            }
        });

        bindings.bind(member.surname).first(new SingleValueBinding<StringPath, String>() {
            @Override
            public Predicate bind(StringPath path, String value) {
                return path.startsWith(value);
            }
        });
    }
}

2 个答案:

答案 0 :(得分:4)

使用Java 7可以通过两种方式实现此目的。第一种方法是创建一个通用基本存储库,将自定义绑定应用于所有已实现的模型存储库。例如:

tid = (long)threadid;

要在实现所有自定义存储库接口时告诉Spring Data使用此基本存储库,只需将其添加为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); } }); } } 注释中的repositoryBaseClass

@EnableJpaRepositories

现在所有的Web服务@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>> { } 查询操作都是不区分大小写的相等测试:

StringPath

第二个选项,您是否希望更好地控制处理其绑定的每个存储库如何创建您想要自定义的存储库的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 } } 版本:

Impl

然后,您可以正常使用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); } }); } } 注释,但必须为要自定义的每个存储库接口创建一个@EnableJpaRepositories实例。

答案 1 :(得分:0)

你可以使用

  

BooleanBuilder
  import com.mysema.query.BooleanBuilder;

构造queryDsl谓词

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有助于减少上述情况下的大量击键