0

我有一个 Spring JPA 搜索条件,如下所示。其中 area 是一个整数。

cb.between(root.get(Property_.area), searchConstraint.getAreaMin(), searchConstraint.getAreaMax())

问题是,当用户在搜索中没有指定上限或下限时,该值为空,这会导致 NPE。我想到的一件事是对空值进行 if 检查并将值设置为 Integer.MAX_VAL 如果它为空作为一种解决方法。这样我可以避免 NPE,但它也会创建很多 if否则检查。所以我想知道是否有更好的方法。

4

3 回答 3

1

我想到了两个更清洁的解决方案:

  • 使用可选项,例如 `Optional.ofNullable(searchConstraint.getAreaMax()).orElse(Integer.MAX_VALUE)
  • areaMin 和 areaMax 应该有合理的默认值,只有当用户提供一些数据时才会被覆盖;应验证数据本身
于 2017-06-05T18:36:27.380 回答
1

如果 getAreaMin 和 getAreaMax 为 NULL,您可以避免/忽略添加此条件。如果 getAreaMin 是 NULL 并且 getAreaMax 不是 NULL 你可以使用 le() 而不是 between ,对于 getAreaMax 和 gt() 方法也是如此;'if' 代码没问题。

像这样的东西:

 if(isNotNull(searchConstraint.getAreaMin()) && isNotNull(searchConstraint.getAreaMax())) {
         cb.between(root.get(Property_.area), searchConstraint.getAreaMin(), searchConstraint.getAreaMax())
 }else{
     if(isNotNull(searchConstraint.getAreaMin()){
          cb.gt(root.get(Property_.area), searchConstraint.getAreaMin());
     }else{
          cb.le(root.get(Property_.area), searchConstraint.getAreaMax());
     }
 } 

或者您可以创建一个 util 方法,例如(但由于性能问题,prev 变体更好):

private Integer getValueOrDefault(Integer value , Integer defaultValue){
    return value==null ? defaultValue : value;
}

执行:cb.between(root.get(Property_.area), getValueOrDefault(searchConstraint.getAreaMin(), Integer.MIN_VALUE), getValueOrDefault(searchConstraint.getAreaMax(), Integer.MAX_VALUE))

于 2017-06-05T18:39:51.223 回答
1

如果两个值都可以为空,我建议将between查询分成两个谓词,然后将它们组合起来。这样你也可以处理它们都为空的情况

List<Predicate> predicates = new ArrayList<>();
if (searchConstraint.getAreaMin() != null)
    predicates.add(cb.gt(root.get(Property_.area), searchConstraint.getAreaMin()))
if (searchConstraint.getAreaMax() != null)
    predicates.add(cb.lt(root.get(Property_.area), searchConstraint.getAreaMax()))
if (predicates.size() > 0)
    cb.and(predicates.toArray(new Predicate[predicates.size()]))
于 2017-06-06T06:17:16.383 回答