2016-08-19 9 views
5

のための高度なコンパレータ、私の春の構成に@EnableSpringDataWebSupport注釈を追加するには、自動的にクエリでPredicateクラスを注入することができます:春 - <a href="http://docs.spring.io/spring-data/commons/docs/current/reference/html/#core.web.type-safe" rel="nofollow">official documentation</a>後QueryDslサポート

@RequestMapping(method = RequestMethod.GET, path="/find") 
public ResponseEntity<PagedResources<FooResource>> find(Pageable pageable, PagedResourcesAssembler<Foo> assembler, @QuerydslPredicate(root = Foo.class) Predicate predicate) { 
    Page<Foo> foos = fooRepository.findAll(predicate, pageable) 
    final ResourceAssemblerSupport<Foo, FooResource> fooResourceAssembler = new ....; 
    final PagedResources<FooResource> pagedResources = assembler.toResource(foos, fooResourceAssembler); 
    return new ResponseEntity<>(pagedResources, HttpStatus.OK); 
} 

GETリクエストを実行するときに、私は簡単に検索することができます。

GET /foo/name?=bob&name=alice&age=20 

これは問題なく動作します。しかし、私は、より高度な検索条件を達成するためにどのように思っていた:

  • >
  • <
  • >=
  • <=

一般的に、私は、数値や日付フィールドにこれらの演算子を適用したいと思います私のデータモデルで。これらの種類の基準はQuerydslでサポートされています。

私は私のクエリパラメータで> (%3E)を追加しようとしたが、それは、それが数として>10を解析することはできません文句を言い、年齢のような数値フィールドのために、たとえば(パース失敗。

クエリで直接、この演算子を使用することが可能ですか?

+0

これを実装する方法はありますか?私は似たようなものを実装しようとしてきましたが、成功しませんでした。 – woemler

+1

@woemler私は実際にその問題を現在駐車していますが、それは遠ざかっていません。私は、クエリパラメータを解析するために私自身のコードを書くことになります。スプリングインジェクション機構と一体化する簡単な方法があるかどうかを確認する必要があります。私がそれをすると、私はおそらく春のgithubリポジトリのアドバイスを求めます。面白いことがあれば答えとしてここに書きます。 – phoenix7360

答えて

1

カスタムクエリDSL(ケースでは、私が春データのMongoDBを使用している事項)結合 - 比較より大きい

あなたは何ができるか

QueryDslPredicateExecutorQuerydslBinderCustomizerを拡張することによって、あなたのリポジトリにバインド独自のQueryDSLを定義している:

public interface FooRepository 
     extends CrudRepository<Foo, Integer>, QueryDslPredicateExecutor<Foo>, QuerydslBinderCustomizer<QFoo> { 

    default void customize(final QuerydslBindings bindings, final QFoo foo) { 
     SingleValueBinding<NumberPath<Integer>, Integer> singleBinding = new SingleValueBinding<NumberPath<Integer>,Integer>(){ 
      @Override 
      public Predicate bind(NumberPath<Integer> path, Integer ageValue) { 
       return path.gt(ageValue); 
      } 
     }; 

     bindings.bind(foo.age).first(singleBinding); 
    } 
} 

私はクエリDSLの専門家だが、私の理解は以下の通りです:

Aバインディングは、特定のフィールドをそのデータベースの列である とどのように比較するかを定義します。

java 8と同じバインディング。ラムダ:(path, ageValue) -> path.gt(ageValue)

パラメータとして提供年齢が データベースの値よりも大きくなるためFOOSをフェッチ:あなたは、URLパラメータの視点からカスタマイズ方法でコードを読まなければなりません。 ?age=10&age=30: -

カスタムクエリDSLが結合比較

別のオプションの間では、このように、あなたのパラメータにバインドされた下限と上限を提供することです。次に、以下のバインドを定義します。

default void customize(final QuerydslBindings bindings, final QFoo foo) { 
    bindings.bind(foo.age).all((path, ageValue) -> { 
     Iterator<? extends Long> it = value.iterator(); 
     return path.between(it.next(), it.next()); 
    }); 
} 
+0

それは面白いです。唯一の問題は、式の実際の解析をカスタマイズすることができないことです。データ型が設定される方法のため、intフィールドを持つことはできませんが、String(たとえば ">"を含む)を解析することはできません。これは春の限界だと思われる。 – phoenix7360

関連する問題