Spring Data JPA存储库检索多个计数

时间:2018-12-09 20:09:42

标签: java spring-boot spring-data-jpa spring-data jpql

我有以下域实体: 对话,其中包含消息列表,每个消息都有一组 newFor 参与者。对于谁尚未阅读列表中的消息。

我正在努力编写存储库接口方法(或查询)以检索该参与者的对话地图,其中包含许多未读消息。

自动取款机我使用以下方法仅检索对话列表:

@Query("SELECT c from Conversation c JOIN c.participants p WHERE :participant IN p")
List<Conversation> findByParticipantsIn(Participant participant, Pageable pageable);

但是我需要以某种方式更新查询,以便能够包括嵌套的未读邮件的计数。像这样:

@Query("SELECT c, count(..my problem is here..) from Conversation c LEFT JOIN c.participants p WHERE :participant IN p ")
List<Object[]> findByParticipantsIn(Participant participant, Pageable pageable);

有人对如何将连接放入 count()有任何想法吗?或者我在这里还能使用什么?

UPD

暴露关系的实体片段:

public class Conversation {
...
    @OneToMany(cascade = CascadeType.ALL)
    private List<Message> messages = new ArrayList<>();
...
    @ManyToMany(fetch = FetchType.EAGER)
    private Set<Participant> participants = new LinkedHashSet<>();
...
}

public class Message {
...
    @ManyToMany(fetch = FetchType.EAGER)
    private Set<Participant> newFor = new HashSet<>();
...
}

参与者不知道消息对话的存在。

1 个答案:

答案 0 :(得分:0)

最后,我可以实现以这种方式检索调用单个存储库方法的数据的目标:

@Query("SELECT c, (SELECT COUNT(m) FROM Message m WHERE m.conversation = c AND :participant MEMBER OF m.newFor) " +
        "FROM Conversation c " +
        "WHERE :participant MEMBER OF c.participants " +
        "GROUP BY c, c.lastMessage.createdDate " +
        "ORDER BY c.lastMessage.createdDate DESC")
List<Object[]> findConversationsPerParticipant(Participant participant, Pageable pageable);

此查询根据上述数据模型检索给定participant的会话以及未读消息的数量。

不确定这种方法是否足够有效,但是我认为它可能比对远程数据库的两次单独调用更快。