Java SpringDataJPA:当集合类型的repository方法参数为空时,如何返回空结果?

Java SpringDataJPA:当集合类型的repository方法参数为空时,如何返回空结果?,java,spring,jpa,spring-data,Java,Spring,Jpa,Spring Data,我使用的是Spring数据JPA v1.10.2 还有一个用例: ClientDao.java: List<Client> getClientsByUnitsIn(@NonNull Collection<Unit> units); 当我为存储库方法添加@Query注释时,也有类似的情况: @Query("SELECT c FROM Client c WHERE c.unit IN (?1)") List<Client> getSpecificClients(

我使用的是Spring数据JPA v1.10.2 还有一个用例:

ClientDao.java

List<Client> getClientsByUnitsIn(@NonNull Collection<Unit> units);
当我为存储库方法添加
@Query
注释时,也有类似的情况:

@Query("SELECT c FROM Client c WHERE c.unit IN (?1)")
List<Client> getSpecificClients(@NonNull Collection<Unit> 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();  
}
请注意,只有当预处理需求频繁出现时,才应使用这种方法,因为它会增加应用程序的复杂性和常规设置

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

@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);
}
在DAO的客户机代码中,您可以通过以下方式调用selectInner()方法:

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

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

使自己的实现看起来很难看。顺便说一句,这需要添加一个虚拟存储库实现类。至于方面,谢谢,我会考虑一下。有一点很有趣:当使用Spring数据查询方法时,它是开箱即用的。但是当使用查询注释时,它不会。为什么?可能有一个选项可以在Spring中配置吗?有了JPA2,它提供了流畅的API,我发现它并没有那么难看。“使用Spring数据查询方法时”是什么意思?即使使用这些方法,您也应该专门处理您的优化:
if(units.isEmpty){return-emptyList();}
当然,来自JPA2的Criteria API看起来不错,但是,来吧,编写
if(…){return-emptyList()
在每个存储库方法中-这不是一个好主意:)AOP是为了避免这些东西而发明的。如果我找不到更好的方法,我会使用AOP。我同意你的观点。AOP确实是一个更好的选择。但我只会在需求有点频繁的情况下介绍它。设置AOP设施来拦截3或4个方法不是一个好主意。你可以增加更新:我发现了一篇关于我的案例的文章:有一个解决方案,但看起来还不够漂亮。
if (units.isEmpty) {
    return emptyList();
}
@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);
}
@Query("SELECT c FROM Client c WHERE c.unit IN (?1)")
List<Client> getSpecificClients(@NonNull Collection<Unit> units)
private ClientDAO clientDAO;
...
List<Unit> units = ...;
List<Client> clients = clientDAO.selectWithIn(units, (o) -> clientDAO.getSpecificClients(o));