Php 通过Symfony中带有spreep的联接表从3个表返回记录

Php 通过Symfony中带有spreep的联接表从3个表返回记录,php,sql,symfony1,propel,Php,Sql,Symfony1,Propel,我有3个数据库表: 文章 物品有标签(其他表格有两个FK) 标签 我当前显示了一个文章列表,下面显示了文章的标记,但是随着列表的变长,查询的数量也会增加 我想循环浏览所有文章,然后依次从每一篇文章中获取标记对象 这可以在一个查询中完成吗?除非我误解了你的问题,否则不要重复任何内容,因为你会产生不同类型的膨胀 执行单个查询,其中“article”与“article\u has\u tag”连接到“tag”。单个查询应该返回它们拥有的标记的指定项目和标记名 我自己也使用原则,所以无法帮助您进行准

我有3个数据库表:

  • 文章
  • 物品有标签(其他表格有两个FK)
  • 标签
我当前显示了一个文章列表,下面显示了文章的标记,但是随着列表的变长,查询的数量也会增加

我想循环浏览所有文章,然后依次从每一篇文章中获取标记对象


这可以在一个查询中完成吗?

除非我误解了你的问题,否则不要重复任何内容,因为你会产生不同类型的膨胀

执行单个查询,其中“article”与“article\u has\u tag”连接到“tag”。单个查询应该返回它们拥有的标记的指定项目和标记名

我自己也使用原则,所以无法帮助您进行准确的查询,但谷歌搜索带来了如下内容:


此外,symfony权威指南(为spreep编写)应该能够帮助您。

我假设您使用的是spreep 1.3或1.4,而不是spreep 1.5(仍在测试版中),后者对这些多连接(部分受条令语法启发)


如果在数据库架构中定义了外键,则在
ArticleHasTagPeer
类中应该有一个静态
doSelectJoinByAll
方法。如果使用此方法,相关的
文章
标记
对象将使用相同的查询进行水合。您仍然可以传入一个
条件
对象,该对象修改
文章
标记
选择条件。我知道这有点奇怪,因为您可能想从文章对象开始,这是推进1.5的变化的驱动因素之一。在Symfony中,您也可以使用,这将在推进1.3中为您提供此功能(推进1.4需要此功能)。事实上,《推进1.5》主要是由DbFinderPlugin的作者弗朗索瓦·扎尼奥托(François Zaniotto)编写的。

简短的回答是

但只要努力,你还是可以做到的。以下是选项列表:

  • 使用插件
  • 编写您自己的对等方法(例如,
    doselectpostwithusers和comments
  • 迁移到推进1.5
  • 转向学说

  • 我相信您正在使用symfony 1.0,因此推进1.2。。。虽然评论中已经描述的方法讨论了替代方法,但至少有一种直接的方法可以解决您的问题:将此函数添加到您的
    ArticlePeer
    类中:

      public static function getTaggedArticles()
      {
        $c = new Criteria();
        //some filters here, e.g. LIMIT or Criteria::IN array
        $ahts = ArticleHasTagPeer::doSelectJoinAll($c);
    
        $articles = array();
        foreach($ahts as $aht)
        {
          if(!isset($articles[$aht->getArticleId()]))
          {
            $articles[$aht->getArticleId()] = $aht->getArticle();
          }
    
          $articles[$aht->getArticleId()]->addTag($aht->getTag());
        }
    
        return $articles;
      }
    
    其中,
    $ahts
    $article\u的缩写,它有\u标签
    。在
    文章
    类(
    protectedarray$collTags
    )中创建一个简单的标记数组,如果它们还不存在,请使用
    addTag()
    方法

    这只执行一个SQL查询,但要认真考虑,如果没有过滤器,我提到您可能会对不必要的数百个对象进行水淹,这是一个重要的性能命中。您可能希望研究如何仅基于doselects()调用进行水合-检查BlahPeer类的

    JOIN
    方法的工作方式,然后了解如何编写自定义
    JOIN
    方法


    无论采用哪种方式,该方法都会以ArticleId作为键构建一个独特的项目数组-如果您需要不同的排序顺序,您可以再次对该数组排序,或者在构建集合时使用不同的数组键来组织该集合。

    这很好。谢谢我总是使用setLimit(),所以开销不应该太大。