2016-08-19 107 views
5

official documentation高級比較,增加@EnableSpringDataWebSupport註解到我的Spring配置允許查詢自動注入Predicate類:春天 - 對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爲數字。

是否有可能直接在查詢中使用該運營商?

(如果它的事項,我使用Spring數據的MongoDB)

+0

你有沒有找到一種方法來實現這一點?我一直在試圖實現類似的東西,但沒有成功。 – woemler

+1

@woemler我實際上已經停止了這個問題,但它不會消失。我想我最終會寫我自己的代碼來解析de查詢參數。我需要檢查是否有一種簡單的方法將其與彈簧注射機構整合。當我這樣做時,我可能會在spring github版本庫中尋求建議。如果我找到一些有趣的東西,將它寫在這裏作爲答案 – phoenix7360

回答

1

自定義查詢DSL結合 - 大於比較

你所能做的就是定義自己的QueryDSL在你的倉庫綁定,通過擴展QueryDslPredicateExecutorQuerydslBinderCustomizer

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專家,但我的理解是這樣的:

一綁定定義瞭如何將特定字段與其數據庫列進行比較。

與java 8 lambda相同的綁定:(path, ageValue) -> path.gt(ageValue)。你必須從URL參數的角度閱讀定製方法的代碼:

取FOOS爲此作爲參數提供的年齡大於 數據庫的價值。

自定義查詢DSL結合 - 比較之間

另一種選擇是提供下限和上限爲您的參數,如:?age=10&age=30。然後,定義以下綁定:

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字段,但解析一個字符串(例如包含「>」)。這似乎是春天的侷限。 – phoenix7360