JPA 规范和 .where 子句中的空参数

JPA Specification and null parameter in .where clause

我写了两个规范,如果它们的参数为 null,return null。

public static Specification<Prodotto> getProdottoByLineaSpec (String linea) {

        if (linea != null) {
            return (root, query, criteriaBuilder) -> {
                return criteriaBuilder.like((root.join("linea")).get("nome"), "%"+linea+"%");
            };
        }
        else return null;
    }

public static Specification<Prodotto> getProdottoByIngSpec (String ing) {

        if (ing != null) {
            return (root, query, criteriaBuilder) -> {
                return criteriaBuilder.like(((root.join("listaQuoteIng")).join("ing")).get("nome"), "%"+ing+"%");
            };
        }
        else return null;
    }

然后我创建了第三个,将前面的与 and 运算符结合在 where 子句中:

public static Specification<Prodotto> getProdottoByMainTraits (String linea, String ing) {

        return Specification.where(getProdottoByLineaSpec(linea).and(getProdottoByIngSpec(ing)));
    }

现在,这是有趣的部分:

最好避免从方法返回 null

您可以使用criteriaBuilder.conjunction() to ignore null parameter Specification. It generates always true Predicate. There is an opposite method criteriaBuilder.disjunction()

public static Specification<Prodotto> getProdottoByLineaSpec (String linea) {
                        
    return (root, query, criteriaBuilder) -> {
        if (linea == null) {                 
            return criteriaBuilder.conjunction();
        }

        return criteriaBuilder.like((root.join("linea")).get("nome"), "%" + linea + "%");            
    }
}

P.S。如果第一个 Specificationnull 试图访问一个方法 and,你会得到 NullPointerException。 要清楚它看起来像这样

Specification.where(null.and(getProdottoByIngSpec(ing)));

但是如果只有第二个 Specificationnull 这个有效

Specification.where(getProdottoByLineaSpec(linea).and(null));

因为and方法参数可以是null