spring+Hibernate 一对多计数行

Posted

技术标签:

【中文标题】spring+Hibernate 一对多计数行【英文标题】:spring+Hibernate one to many count rows 【发布时间】:2017-06-11 00:58:50 【问题描述】:

我在休眠中的“发布”和“评论”实体之间存在一对多关系。一个帖子可以有多个 cmets (Post) 1 - N (Comment),因此 comment 持有 post (post_id) 的外键。问题是当我为我的控制器获取帖子列表时,每个帖子我还想包括分配给这个帖子的评论数量。因此,如果有一些帖子列表,我想附加到该帖子下方的 cmets 的数据编号。

我创建了 PostWithCommentsCountDTO,其中包含可以容纳 cmets 数量的附加字段,我已经完成了转换器等。

但是我应该在哪里以及如何实际获取 cmets 的数量,我该怎么做呢?

整个架构看起来像这样 控制器 - PostWithCommentsCountDTO - PostService - PostRepository - Post 控制器 - CommentDTO - CommentService - CommentRepository - 评论

【问题讨论】:

请提供足够的信息以帮助其他人重现该问题,包括任何相关代码。看到这个寻求帮助:***.com/help/how-to-ask 【参考方案1】:

请阅读点15.6 here 您可以使用 PostWithCommentsCountDTO 的所有字段创建构造函数。之后,您可以在 HQL 查询中使用它,如我添加的链接中所述。在您的查询中,您可以按“post_id”加入帖子和评论,按“post_id”对它们进行分组,并在选择语句中使用 count(post_id)。 所以您的查询将如下所示:

select new PostWithCommentsCountDTO (p.id, /and all other fields.../ , count(post_id)) from Post as p left join Comments as c on p.id=c.post_id where /some where statement if needed .../ group by c.post_id

这意味着您可以在存储库级别收集您的 DTO:

public List<PostWithCommentsCountDTO> getWithCommentsCount(...)
     return (List<PostWithCommentsCountDTO>) getSession().createQuery(...).setParameter(...).list();

【讨论】:

从存储库返回 dto 不是“不好的做法”,因为我听说你必须返回实体? @Rickmoriarty 用于一般方法,例如 getAll(...)getById(...) 和与它们类似的方法您应该返回实体,但对于某些特定方法,您不需要更好地使用表中的所有数据来使用 DTO . @Rickmoriarty 例如,如果您从数据库中获取所有订单并将它们分组到服务层,您需要从某个订单表中选择所有产品名称及其数量您必须从数据库中获取大量不需要的数据这会增加您的流量和执行方法的时间。如果您的数据库与您的应用程序不在同一台机器上,则执行时间会更大,应用程序会更慢。但是您可以在数据库服务器中执行简单的 `group by ... ` 和 `count (...) `,并且只从数据库中获取聚合数据,这样可以更快地工作,并且在应用程序和数据库之间使用更少的流量。 @Rickmoriarty 这使得从存储库级别返回 DTO 的解决方案更加优化,并且可能在将来有人在您的请求期间更新数据库时减少错误数量。总结:对于一般获取方法,最好从存储库返回实体,但对于特定计算或聚合方法,最好从存储库返回预先计算的 DTO

以上是关于spring+Hibernate 一对多计数行的主要内容,如果未能解决你的问题,请参考以下文章

使用一对多映射保存对象时出现 Spring + Hibernate id 问题

无法让spring boot hibernate rest api返回一对多关系

使用 H2、JPA 注释和 Hibernate 问题的一对多关联

面试Hibernate常见问题总结02

在hibernate内如何配置一对一的关系

Hibernate一对多实例