JPA的toPredicate重构方法支持Java 7和8

时间:2019-06-25 13:05:31

标签: java spring-data-jpa

我现在已经使用toPredicate()方法进行了一些编码,我想对其进行重构,以便也可以在Java 7中使用它。

我已经在下面发布了一些到目前为止已经完成的示例代码。

EntitySpecification.java

public class EntitySpecification {

    public static Specification<MyEntity> textInAllColumns(String text) {

        if (!text.contains("%")) {
            text = "%"+text+"%";
        }
        final String finalText = text;

        return new Specification<MyEntity>() {
            @Override
            public Predicate toPredicate(Root<MyEntity> root, CriteriaQuery<?> cq, CriteriaBuilder builder) {
                return builder.or(root.getModel().getDeclaredSingularAttributes().stream().filter(a-> {
                    if (a.getJavaType().getSimpleName().equalsIgnoreCase("string")) {
                        return true;
                    }
                    else {
                        return false;
                }}).map(a -> builder.like(root.get(a.getName()), finalText)
                    ).toArray(Predicate[]::new)
                );
            }
        };
    }

 }

2 个答案:

答案 0 :(得分:1)

您必须替换

- stream
- filter
- map

因为Java 7中没有Streaming API。

通过替换,我的意思是您必须遍历getDeclaredSingularAttributes()并过滤元素并将其映射。

由于现在有方法引用,因此Predicate[]::new也必须替换为new Predicate[]

正如Rashin所说,如果将源级别设置为Java 7,则可以使用IDE来完成。

答案 1 :(得分:1)

lambda表达式(->)是Java 8附带的。要使用Java 7中的代码,必须将其替换为匿名类。
如果您使用像IntelliJ这样的IDE,它可以为您完成这项工作。将光标移至->,然后按ALT + ENTER。应该会出现一个弹出窗口,并且应该有Replace lambda with anonymous class的选项。

.filter(a -> {
    if (a.getJavaType().getSimpleName().equalsIgnoreCase("string")) {
        return true;
    } else {
        return false;
    }
})

.filter(new java.util.function.Predicate<SingularAttribute<MyEntity, ?>>() {
  @Override
  public boolean test(SingularAttribute<MyEntity, ?> a) {
      if (a.getJavaType().getSimpleName().equalsIgnoreCase("string")) {
          return true;
      } else {
          return false;
      }
  }
})

此外,您还必须摆脱java.util.function包中正在使用的所有内容。

您可以将.filter()替换为for循环和其中的if语句。对于.map(),您必须使用for循环修改先前过滤的集合。

new Specification<MyEntity>() {
  @Override
  public Predicate toPredicate(Root<MyEntity> root, CriteriaQuery<?> cq, CriteriaBuilder builder) {
      List<SingularAttribute<MyEntity, ?>> tempAttributes = new ArrayList<>();
      for (SingularAttribute<MyEntity, ?> attribute : root.getModel().getDeclaredSingularAttributes()) {
          if (attribute.getJavaType().getSimpleName().equalsIgnoreCase("string")) {
              tempAttributes.add(attribute);
          }
      }

      final Predicate[] predicates = new Predicate[tempAttributes.size()];

      for (int i = 0; i < tempAttributes.size(); i++) {
          predicates[i] = builder.like(root.<MyEntity>get(tempAttributes.get(i).getName()), finalText);
      }

      return builder.or(predicates);
  }
};

我自己没有尝试过,但这应该可行,或者至少可以为您提供第一步。