4

我有以下匹配器:

Example.of(
    user,
    ExampleMatcher.matching()
                  .withMatcher("name", contains().ignoreCase())
                  .withMatcher("phoneNumber", contains())
)

它工作正常,除了null值。例如,它不会返回电话号码为 的用户NULL

我试图遵循以包含这些NULL值,但它没有用:

Example.of(
    user,
    ExampleMatcher.matching()
                  .withMatcher("name", contains().ignoreCase())
                      .withIncludeNullValues()
                  .withMatcher("phoneNumber", contains())
                      .withIncludeNullValues()
)

生成的 SQL 如下:

select
    user0_.id as id1_9_,
    user0_.document_expiry_date as document2_9_,
    user0_.document_type as document3_9_,
    user0_.document_url as document4_9_,
    user0_.email as email5_9_,
    user0_.name as name6_9_,
    user0_.phone_number as phone_nu7_9_
from
    user user0_
where
    (lower(user0_.name) like ?)
    and (user0_.id is null)
    and (user0_.document_type is null)
    and (user0_.document_url is null)
    and (user0_.email is null)
    and (user0_.phone_number like ?)
    and (user0_.document_expiry_date is null)

如何将其配置为也包含带有NULL列的行?

4

2 回答 2

1

您可以JpaSpecificationExecutor<T>在您的存储库中实现并使用findAll(Specification specification),并像参数一样设置:


//My solution, create a specification with predicate and add example.
 public Specification<MaestroPlasticoTebca> specificationAttributeNull(boolean isNull, Example<MaestroPlasticoTebca> example, String attributeName) {
        return (root, query, builder) -> {
            final List<Predicate> predicates = new ArrayList<>();

            if (isNull) {
                predicates.add(builder.isNull(root.get(attributeName)));
            } else {
                predicates.add(builder.isNotNull(root.get(attributeName)));
            }

            predicates.add(QueryByExamplePredicateBuilder.getPredicate(root, builder, example));
            return builder.and(predicates.toArray(new Predicate[0]));
        };

    }

并使用它:

Example example = Example.of(
    user,
    ExampleMatcher.matching()
                  .withMatcher("name", contains().ignoreCase())
);

repository.findAll(specificationAttributeNull(true, example, "phoneNumber"));

于 2020-04-20T22:36:59.857 回答
1

面临同样的问题,但我认为没有办法实现这个目标。这是withMatcher方法的源代码:

public ExampleMatcher withMatcher(String propertyPath, ExampleMatcher.GenericPropertyMatcher genericPropertyMatcher) {
    Assert.hasText(propertyPath, "PropertyPath must not be empty!");
    Assert.notNull(genericPropertyMatcher, "GenericPropertyMatcher must not be empty!");
    ExampleMatcher.PropertySpecifiers propertySpecifiers = new ExampleMatcher.PropertySpecifiers(this.propertySpecifiers);
    ExampleMatcher.PropertySpecifier propertySpecifier = new ExampleMatcher.PropertySpecifier(propertyPath);
    if (genericPropertyMatcher.ignoreCase != null) {
        propertySpecifier = propertySpecifier.withIgnoreCase(genericPropertyMatcher.ignoreCase);
    }

    if (genericPropertyMatcher.stringMatcher != null) {
        propertySpecifier = propertySpecifier.withStringMatcher(genericPropertyMatcher.stringMatcher);
    }

    if (genericPropertyMatcher.valueTransformer != null) {
        propertySpecifier = propertySpecifier.withValueTransformer(genericPropertyMatcher.valueTransformer);
    }

    propertySpecifiers.add(propertySpecifier);
    return new ExampleMatcher(this.nullHandler, this.defaultStringMatcher, propertySpecifiers, this.ignoredPaths, this.defaultIgnoreCase, this.mode);
}

此方法返回一个 ExampleMatcher,其“全局”nullHandler 应用于所有字段。这意味着,您不能为某些特殊字段指定不同的 nullHander。

于 2018-07-13T02:49:35.397 回答