【问题标题】:How to configure query by example to include null values?如何通过示例配置查询以包含空值?
【发布时间】:2023-03-14 00:07:01
【问题描述】:

我有以下匹配器:

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 列的行?

【问题讨论】:

  • 请添加生成的SQL语句。
  • @JensSchauder 在哪里可以找到生成的 SQL 语句?
  • 配置你的 JPA 实现来记录它......然后你会在日志中找到它。
  • @JensSchauder 添加了生成的 SQL 语句。

标签: spring-data-jpa query-by-example


【解决方案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。

【讨论】:

    【解决方案2】:

    您可以在您的存储库中实现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"));
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 2012-12-04
      • 1970-01-01
      相关资源
      最近更新 更多