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