2016-07-25 192 views
0

我有一個spring-boot應用程序,我想要一個動態查詢條件,即我想創建一個方法,可以接收以下可選參數:Age和名稱。我的問題是,這些參數是可選的,這意味着它們有時可能是NULL,並且我想動態地構建我的查詢,例如,如果參數不爲空或空,我將它們作爲條件放入我的查詢中,否則,噸。在Spring-Boot中使用動態條件查詢擴展CrudRepository

我發現這個問題的解決方案基本上是爲我的存儲庫(UserRepositoryCustomImpl)創建一個自定義實現,並自己構建查詢。然而,我想知道是否沒有「彈簧導向解決方案」,就像一些註釋一樣,或者我可以說,「嘿,使用這個地圖,動態地建立這個查詢」。

+1

這些問題的第一步,閱讀[手冊](http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#specifications)。 –

+1

要麼使用規範要麼創建兩種方法並在服務層進行檢查。你也可以使用或我猜,但不知道它是如何工作的空值 – Sarief

+0

@ M.Deinum已閱讀手冊,並沒有找到我需要在那裏的解決方案。否則,我不會在這裏問問題,並浪費他人的時間。 – tsukanomon

回答

0

我覺得我已經住過同樣的情況:我的HTML表單有N個過濾器,但我希望它們只適用於搜索,如果它們被選中或更改。一旦你模擬你的表單綁定與它的各自的選擇,輸入等...從視圖,如果任何這些領域沒有選擇或具有默認值,只是想忽略,但仍然使用的方便和容易的春天Repository(在我的情況下JpaRespository)。

用我小小的Spring透視圖我試過使用Specification方法(IMO比實現你的定製倉庫更好)。它完美地工作,但不知道它是否是最好的方法。

下面是一個官員,在春天例如https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/


在這裏,一個個人的例子有點簡單化(也可能打破一些最佳的編碼實踐,目的是可以理解的):

MyObjectRepository.java

MyObjectServiceImpl.java

@Service("MyObjectService") 
public class MyObjectServiceImpl implements MyObjectService { 

@Autowired 
MyObjectRepository myObjectRespository; 

@Override 
public Page<MyObject> getAllMyObjectByFields(int pageIndex, FormMyObject formMyObject) { 
    Specification<MyObject> spec = new Specification<MyObject>() { 
      @Override 
      public Predicate toPredicate(Root<MyObject> root, CriteriaQuery<?> query, CriteriaBuilder builder) { 
      if (formMyObject == null) { 
       throw new IllegalStateException("At least one parameter should be provided to construct complex query"); 
      } 
      List<Predicate> predicates = new ArrayList<Predicate>(); 
       // only if the content is present add a criteria to the search, you decide/know if will be null, or empty... 
       if (formMyObject.getYourField() != null && formMyObject.getYourField().length() > 0) { 
        predicates.add(
          builder.and(builder.equal(root.get("field"), formMyObject.getYourField()))); 
       } 

       // add as many criteria as you want/need 
       if(){ 
        predicates.add(...); 
       } 


       Predicate[] predicatesArray = new Predicate[predicates.size()]; 
      return builder.and(predicates.toArray(predicatesArray)); 
      } 
    }; 

    PageRequest page = new PageRequest(pageIndex, formMyObject.getMaxResult());  
    // using the built in findAll method from Repository with dynamic custom filters 
    return myObjectRespository.findAll(spec, page);