假设我有以下 JPA 方法:
public List<FrequencyCode> findAllByNameContainingAndAllowExplicitDosingTimesEqualsOrderByName(String name, Boolean allowExplicitDosingTimes);
用户可以通过输入框和选择框来过滤这些对象列表并调用此方法:
在此情况下,布尔值可以为true、false或null,如果用户不使用该字段进行搜索,则为null。看起来JPA实际上正在搜索null值,而我希望它忽略任何null值。我已经能够通过以下代码使这个组合搜索工作:
@Override
public List<FrequencyCode> findAllWithFilters(String name, Boolean allowExplicitDosingTimes)
{
if (allowExplicitDosingTimes == null)
{
return ((FrequencyCodeRepository) baseRepository).findAllByNameContainingOrderByName(name);
}
else if (allowExplicitDosingTimes == true)
{
return ((FrequencyCodeRepository) baseRepository).findAllByNameContainingAndAllowExplicitDosingTimesTrueOrderByName(name);
}
else if (allowExplicitDosingTimes == false)
{
return ((FrequencyCodeRepository) baseRepository).findAllByNameContainingAndAllowExplicitDosingTimesFalseOrderByName(name);
}
return null;
}
这个方案是可行的,但显然,在有8个搜索选项的页面上,这将成为一种噩梦。字符串参数没有这个问题,因为当用户不选择筛选器时,它们实际上是一个空字符串。结合包含关键字,任何值都包含“”,所以它的行为就像忽略了该参数,这正是我想要的其他类型。是否有一种方法使JPA findAll...()方法简单地忽略空参数?
******解决方案******
以下是如何借助已接受的答案使其工作的方法:
FrequencyCode fc = new FrequencyCode();
fc.setName(name);
fc.setAllowExplicitDosingTimes(allowExplicitDosingTimes);
ExampleMatcher matcher = ExampleMatcher.matching()
.withMatcher("name", match -> match.contains())
.withMatcher("allowExplicitDosingTimes", match -> match.exact())
.withIgnorePaths("id", "uuid")
.withIgnoreNullValues();
Example<FrequencyCode> example = Example.of(fc, matcher);
List<FrequencyCode> frequencyCodes = ((FrequencyCodeRepository) baseRepository).findAll(example);
你必须让它忽略任何ID字段或者其他你不想用来搜索的字段,但这是非常强大的!
谢谢!