我正在编写一个存储库方法,我想使用注释来实现它@Query
。该请求应检索所有用户的列表,按用户留下的消息数排序。
这样的方法可能如下所示:
@Query(value = """
SELECT u FROM User u
INNER JOIN u.postedMessages
GROUP BY u.id
ORDER BY COUNT(*)
""")
List<User> findAllByOrderByMessagesCount();
但是,我希望能够将排序方向作为参数传递给该方法。例如,只是一个采用值ASC
/的字符串DESC
。我正在想象这样的事情:
@Query(value = """
SELECT u FROM User u
INNER JOIN u.postedMessages
GROUP BY u.id
ORDER BY COUNT(*)
:direction
""")
List<User> findAllByOrderByMessagesCount(@Param("direction") String direction);
然而,这是行不通的,因为据我了解,这种替换只能在某些表达式的框架内进行,例如比较等WHERE
。
我想出了一个使用类中对象形式的参数的选项Sort
。你可以这样传递:
JpaSort.unsafe(direction, "COUNT(*)")
这将完成我想要的,在这里,正如你所看到的,设置方向没有问题。
但我不喜欢这样一个事实:排序实际上是我实现的存储库方法的主要任务。如果COUNT(*)
我们将它转移到来自外部世界的方法调用中,那么它似乎会有些丑陋:我们将其逻辑的一半与方法分开,而方法本身却显得有些愚蠢。
因此,问题是:如何将确定排序方向的子字符串@Query
从方法参数替换到注释中?
当然,我完全有可能正在尝试做一些完全可怕的事情,所以如果有关于如何实现返回排序列表并取决于排序方向的方法的更好想法,那么请。
我设法实现了我想要的。没有像我最初假设的那样使用 Spring Data JPA,而是使用常规 SQL 的语法:
看起来相对笨重,但达到了我的预期。
现在我们可以轻松地从服务调用此方法,仅将排序方向传递给它。该方法本身执行其所有逻辑:它连接表、组并立即排序,与此逻辑密不可分。