0

我正在使用 Spring 和 Hibernate 编写一个 Web 应用程序,它将人员、组、帖子、附件、评论等相当复杂的域模型映射到 mysql 数据库中。这个问题源于尝试优化评论查询,但也适用于网站的其他方面。

为了简化问题,评论与帖子具有多对一关系,而帖子与群组具有多对一关系。每个组都有一个基本 url ({/group_slug}),每个帖子都可以通过该 url 后跟斜杠和帖子 ID (/{group_slug}/{post_slug}) 访问。这些帖子有对其父级的引用,并以瞬态方法计算它们的 url,该方法向父级询问其 url 并将其 slug 附加到它的末尾。如果评论想要它的 url,它会询问它的父级(帖子),然后查询组并创建 url。它工作正常,除了以下性能问题:

在主页上,我想在一个列表中显示来自每个用户组的所有最近评论。在每条评论下方应该是一个链接,指向该评论所写的帖子。重要的是这是一个相对快速的查询,但是对于当前的模型,我无法弄清楚如何有效地做到这一点。我当前的休眠查询(jpql)看起来像这样,对于用户所属的每个组:

select c from Comment c where c.target.group.id = :groupId and c.dateCreated > :date

但是随后要获取目标项目的每个 url(由于休眠急切地加载从评论到目标然后是目标到组的一对多关系),目标和组都必须从数据库中加载,对于每条评论。

有没有更好的方法来组织这个查询,或者重新设计域模型,这样我就不必每次都加载这么多数据?如果不是,那么每次创建新评论时,对数据库进行反规范化并将评论父级的 url 与它一起存储在数据库中的缺点是什么?没有一个实体经常更改 url,但帖子的 slug 可能会更改。我可以通过遍历所有关于任何 slug 更改的相关评论并更新 url 来处理这种情况,但这似乎仍然违反最佳实践。

4

1 回答 1

0

您可以在查询中急切加载它以防止 SELECT N+1 发生

select c from Comment c join fetch c.target t join fetch t.group g where g.id = :groupId and c.dateCreated > :date
于 2012-08-20T04:15:41.623 回答