2016-07-25 188 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);