ORM:用于过滤实体上的惰性集合的模式

时间:2012-02-28 22:20:07

标签: hibernate orm doctrine-orm

我发布这个问题作为语言和框架无关,因为我认为这可能是ORM框架的一般性。

我想知道是否有人可以告诉我是否存在以下用例的设计模式:

用例

该系统是使用ORM Framework运行的模型 - 视图 - 控制器Web应用程序。

游戏中有两个实体PollVote

一个Pollone-to-many的关系Vote,投票位于 Lazy Loaded 的集合中。

系统中的每个用户只能投票一次。

为了用户体验,View通过仅针对当前用户尚未投票的民意调查显示控件来适应,因此Poll有一个方法(伪代码) :

public boolean hasVoteFor(user) {
    for each vote
        if vote.user == user
            return true

    return false
}

因此,当View通过Poll传递Controller时,它可以通过执行if poll.hasVoteFor(user)来呈现正确的控件。

问题

上述方法的问题在于,由于集合是Lazy Loaded,因此迭代它可能会成为非常大的内存和放大器。数据库密集型。

使用SQL / DQL / SQL显然可以使用数据库直接查询用户投票的Poll实体,但是任何此类查询都应该在存储库中进行,我假设View 1}}不应该有权访问。

方案吗

所以我想知道是否有设计模式来解决这个问题。

  • Controller是否应该使用hasVoteFor(poll, user)等方法?如果视图呈现多个轮询,则会出现问题。 (对于每个民意调查,具有许多条件的查询会更快,而不是进行多次选择,因为View会迭代Poll s。

  • Controller是否应该使用存储库查询用户预先投票的所有Poll并将其与View一起传递给Poll (或Poll的数组)。这种打破了Poll hasVoteFor方法的整洁抽象 - 是不是ORM应该让你只考虑你的对象? ;)

  • 在实践中常用的其他一些我忽视的解决方案?

1 个答案:

答案 0 :(得分:1)

ORM只是一个帮助您使用数据库的工具。但是,数据库仍然是您有效查询要显示的数据的最佳工具。使用ORM而不理解和关心数据库以及生成的查询是灾难的一种方法。

你的第二个解决方案比第一个更好,但它仍然没有那么合乎逻辑和高效。

控制器可以执行返回PollWithVoteFlag实例列表的查询,而不是查询要显示的轮询或轮询,然后查询用户已投票的轮询,并将这两个集合传递给视图,控制器可以执行查询,包含每个民意调查数据,以及表明民意调查是否已由用户投票的标志。