【发布时间】:2012-08-16 23:52:04
【问题描述】:
我正在使用 Spring 和 Hibernate 编写一个 Web 应用程序,它将人员、组、帖子、附件、cmets 等相当复杂的域模型映射到 mysql 数据库中。这个问题源于尝试优化 cmets 的查询,但也适用于网站的其他方面。
为简化问题,cmets 与帖子具有多:1 关系,而帖子与群组具有多:1 关系。每个组都有一个基本 url ({/group_slug}),每个帖子都可以通过该 url 后跟斜杠和帖子 ID (/{group_slug}/{post_slug}) 访问。这些帖子有对其父级的引用,并以瞬态方法计算它们的 url,该方法向父级询问其 url 并将其 slug 附加到它的末尾。如果评论想要它的 url,它会询问它的父级(帖子),然后查询组并创建 url。它工作正常,除了以下性能问题:
在主页上,我想在一个列表中显示来自每个用户组的所有最近的 cmets。在每条评论下方应该是一个链接,指向该评论所写的帖子。重要的是这是一个相对快速的查询,但是对于当前的模型,我无法弄清楚如何有效地做到这一点。对于用户所属的每个组,我当前的休眠查询 (jpql) 如下所示:
select c from Comment c where c.target.group.id = :groupId and c.dateCreated > :date
但随后要获取目标项目的每个 url(由于休眠急切地加载从评论到目标然后目标到组的一对多关系),目标和组都必须从数据库中加载同样,对于每条评论。
有没有更好的方法来组织这个查询,或者重新设计域模型,这样我就不必每次都加载这么多数据?如果不是,那么每次创建新评论时,对数据库进行反规范化并将评论父级的 url 与它一起存储在数据库中的缺点是什么?没有一个实体经常更改 url,但帖子的 slug 可能会更改。我可以通过在任何 slug 更改上遍历所有关联的 cmets 并更新 url 来处理这种情况,但这似乎仍然违反最佳实践。
【问题讨论】:
-
在你的域对象中生成一个 url 对我来说似乎不是最佳实践。我不知道你使用什么前端,但是应该在那里生成 url。