java - Spring 数据JPA : how to return empty result when repository method parameter of Collection type is empty?

标签 java spring jpa spring-data

我正在使用 Spring Data JPA v1.10.2 还有一个用例:

ClientDao.java:

List<Client> getClientsByUnitsIn(@NonNull Collection<Unit> units);

此方法生成如下 SQL 查询:

SELECT * FROM clients WHERE units in (?1)

当我为存储库方法添加 @Query 注解时,也会出现类似的情况:

@Query("SELECT c FROM Client c WHERE c.unit IN (?1)")
List<Client> getSpecificClients(@NonNull Collection<Unit> units)

但在许多情况下,参数units可能为空。在这种情况下,该方法应该返回空结果,但它只是失败并显示有关错误 SQL 语句的消息。

我使用一种解决方法:向存储库添加默认方法,如下所示:

default List<Client> getSpecificClientsOrEmpty(@NonNull Collection<Unit> units){
    if (units.isEmpty) {
        return emptyList();
    }
    return getSpecificClients(units);
}

但我不喜欢这种解决方法:

  • 我必须为每种情况创建一个额外的方法
  • 我必须检查代码中是否仅使用了默认方法,因为没有编译时检查,如果我错过了某些使用,则会收到运行时异常。

有没有人有更好的解决方案?

最佳答案

1) 使用 getSpecificClients() 存储库实现中的样板代码编写您自己的查询:

public List<Client> getSpecificClients(@NonNull Collection<Unit> units){
    if (units.isEmpty()) {
        return emptyList();
    }
    return em.createQuery("SELECT c FROM Client c WHERE c.unit IN (?1)", Unit.class)
             .setParameter(1, units)
             .getResultList();  
}

如果这种预处理在您的存储库中是不常见的要求,那么应该优先考虑这种方式。
这种方式有点冗长,但对于少数情况来说仍然可以接受。

2)用AOP横向制作。
定义一个 Aspect 在您需要的每个方法之前执行此处理:

if (units.isEmpty) {
    return emptyList();
}

请注意,只有当预处理要求发生得足够频繁时才应使用这种方法,因为它会增加应用程序的复杂性和一般设置。

3) 您可以在基本接口(interface)存储库中创建一个通用默认方法,该方法接受 Function 作为参数,以便能够将任何要执行的方法传递给该方法:

@SuppressWarnings("unchecked")
default<T, U> List<U> selectWithIn(Collection<T> valueForInClause, Function<Collection<T>, List<U>> function) {
    if (valueForInClause.isEmpty()) {
        return new ArrayList<U>();
    }
    return function.apply(valueForInClause);
}

ClientDAO 类中,您仍然会有这个:

@Query("SELECT c FROM Client c WHERE c.unit IN (?1)")
List<Client> getSpecificClients(@NonNull Collection<Unit> units)

在 DAO 的客户端代码中,您可以通过以下方式调用 selectWithIn() 方法:

private ClientDAO clientDAO;
...
List<Unit> units = ...;
List<Client> clients = clientDAO.selectWithIn(units, (o) -> clientDAO.getSpecificClients(o));

它并不太冗长,它节省了一些代码行,但我真的不喜欢这种方式,因为它对 DAO 客户端类进行了更复杂的单元测试。

关于java - Spring 数据JPA : how to return empty result when repository method parameter of Collection type is empty?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48071990/

相关文章:

java - 多个案例 - 基于值范围而不是 Java 中的单个值进行测试?

java - URLDecode.decode 方法在 Java 中未按预期工作

java - 网络服务器的 out.flush() 问题

java - 如何使用 Spring Security 保护 Vaadin 流应用程序

java - JPA根据列名更新

java - 如何使用 EJBQL 选择实体集合并将其作为参数传递给 Bean?

java - Liferay 并发文件条目上传

java - 始终应用的方法的第一次模拟

java - 监控应用程序框架

java - 我可以在 EJBQL 中通过未映射到数据库列的函数进行排序吗?