通过Symfony中的Propel连接表从3个表中返回记录

时间:2010-03-14 23:24:43

标签: php sql symfony1 propel

我有3个数据库表:

  • 制品
  • article_has_tag(2张FK到其他表格)
  • 标签

我目前显示的文章列表中显示了文章的标签,但随着列表变长,查询数量也会增加。

我想循环遍历所有文章并依次从每个文章中获取标记对象。

可以在1推进查询中完成吗?

4 个答案:

答案 0 :(得分:1)

我相信你正在使用symfony 1.0,因此Propel 1.2 ......虽然评论中已经描述的方法谈论了替代方法,但至少可以解决你的问题:将此函数添加到{{1 class:

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_has_tags类(Article)中创建一个简单的标记数组以及protected array $collTags方法,如果它们尚不存在以便于此操作。

这只会执行一个SQL查询,但请认真考虑,如果没有我提到的过滤器,你可能会不必要地保护数百个对象,这是一个重大的性能损失。您可能想要仅根据doSelectRS()调用来研究如何进行水合 - 检查您的BlahPeer类以了解其addTag()方法的工作方式,然后this link了解如何编写自定义JOIN方法

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

答案 1 :(得分:0)

除非我误解你的问题,否则不要循环任何事情,因为你会产生不同类型的膨胀。

将“article”加入“article_has_tag”的单个查询加入“tag”。单个查询应返回指定的文章和标签名称。

我自己使用Doctrine,所以无法帮助您完成确切的查询,但Googling会提出这样的内容:http://www.tech-recipes.com/rx/2924/symfony_propel_how_to_left_join/

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

答案 2 :(得分:0)

我假设您正在使用Propel 1.3或1.4,而不是Propel 1.5(仍处于测试阶段),因为后者对这些多个连接有a very natural support(部分受到Doctrine语法的启发)

如果在数据库模式中定义了外键,则doSelectJoinByAll类中应该有一个静态ArticleHasTagPeer方法。如果您使用此方法,相关的ArticleTag对象将使用相同的查询进行水合。您仍然可以传入修改CriteriaArticle选择条件的Tag对象。我知道这有点奇怪,因为你可能想从Article对象开始,这是Propel 1.5变化的驱动因素之一。在Symfony中,你也可以使用DbFinderPlugin,这已经在Propel 1.3中为你提供了这个功能(Propel 1.4需要a small patch)。事实上,Propel 1.5主要是由DbFinderPlugin的作者FrançoisZaniotto编写的。

答案 3 :(得分:-2)

简短回答

但是通过一些努力,你仍然可以做到这一点。以下是选项列表:

  1. 使用dbFinderPlugin插件
  2. 编写您自己的对等方法(例如,doSelectPostWithUsersAndComments)。
  3. 迁移到Propel 1.5
  4. 迁移至Doctrine