3

背景

我在一个投资组合网站上工作,这个网站相当简单,大部分作品都在画廊里。我有一组数据库表,它们都链接起来以不同的方式检索和过滤画廊,从顶部开始,如下所示:

GalleryCategory-> Gallery->GalleryImage


问题

我面临的问题仅在画廊类别页面上,我正在查看给定类别中的所有画廊,然后画廊中的画廊图像返回。

我的控制器目前看起来像这样:

public function galleryCategoryAction($categoryId)
{
    $em = $this->getDoctrine()->getManager();

    $category  = $em->getRepository('SeerUKDWrightGalleryBundle:GalleryCategory')->findById($categoryId);
    $galleries = $category->getGalleries();

    $galleryImages = [ ];
    foreach ($galleries as $i => $gallery)
    {
        $galleryImages[$gallery->getId()] = $em->getRepository('SeerUKDWrightGalleryBundle:GalleryImage')
            ->findOneByGalleryId($gallery->getId());
    }

    return $this->render('SeerUKDWrightGalleryBundle:Gallery:category.html.twig', array(
        'category'      => $category,
        'galleries'     => $galleries,
        'galleryImages' => $galleryImages
    ));
}

现在,尽管这确实有效,但正是我想要的,我觉得它只是......错了!将画廊归入一个类别既好又干净:

$category  = $em->getRepository('SeerUKDWrightGalleryBundle:GalleryCategory')->findById($categoryId);
$galleries = $category->getGalleries();

但是,我看到获得每个画廊的第一张图像的唯一方法是遍历它们并检索每个实体。就像我说的,这似乎是错误的。

我所拥有的唯一改进这一点的其他建议是使用画廊实体中的实体管理器来获取实体内的图像,这当然会破坏 Doctrine 的用途。


结论

总之,我该如何做得更好?必须有一个地方可以做得更好,我只是 Symfony 的新手。查看文档没有帮助...


额外细节

我忘了说,仍然能够使用实体的能力是必要的,我对实体有一些稍后使用的方法。例如,在 GalleryImage 实体中,我有获取图像的系统路径和 Web 路径的方法。我仍然需要能够使用这些。

4

1 回答 1

6

你可以做很多事情;我将列出要点列表,以便您发现它们。

延迟加载会产生额外的查询;如果您知道要提取关联实体的集合,则可能需要加入这些实体。

以下代码生成两个查询

$category  = $em->getRepository('SeerUKDWrightGalleryBundle:GalleryCategory')->findById($categoryId);
$galleries = $category->getGalleries();

如果您遵循文档,您应该执行以下操作(最好在实体的存储库类中)

$em = $this->getDoctrine()->getManager();

$query = $em->createQuery(
    'SELECT gc, g
     FROM SeerUKDWrightGalleryBundle:GalleryCategory gc
     LEFT JOIN gc.galleries g
     WHERE gc.id = :categoryId'
)->setParameter('categoryId', $categoryId);

$category = $query->getResult();

这只是一个查询。

如果您有很多画廊,比如说 100,000 个,您的服务器将很快耗尽内存,因此您可能需要分页或使用延迟加载和额外的延迟加载选项

如果您想进一步抽象代码,可以在存储库和控制器之间添加服务。

  • 存储库将从数据库中获取数据
  • 服务将调用存储库、获取数据并对其进行操作(如 Helper 类)。
  • 控制器将调用服务并将数据注入模板层(除其他外)。

如果要获取每个图库的第一张图片,可以使用语句和语句创建SELECT查询。这样,您对所有画廊进行一次查询,而不是“x”查询(如果有 100,000 个画廊,则为 100,000 次查询)。INGROUP BY

于 2013-03-22T20:49:49.350 回答