我正在使用Propel ORM和Propel的新手.我需要一些帮助从一个表中选择数据,但我无法做出正确的查询.我有一个这样的表(注意:不是实际的表,但相同的主要):
+---------------------+
| ID | Page | Parent |
+---------------------+
| 1 | A | 0 |
| 2 | B | 0 |
| 3 | C | 2 |
| 4 | D | 3 |
| 5 | E | 1 |
| 6 | F | 0 |
| 7 | G | 3 |
| 8 | H | 4 |
| 9 | I | 6 |
| 10 | J | 5 |
+---------------------+
加载页面时,此表为我提供了类似树的结构.在使用propel之前,我有一个带有’loadPages’函数的类,它将内部页面嵌套在一个名为$nested的数组中,该类看起来像这样(注意:不是实际函数只是一个近似表示):
function loadPages($parent=0, $data){
$sql = "sql query here to select pages where parent = $parent";
while($results){
$pages = new Pages();
$pages->setId(blah blah);
$pages->setPage(blah blah);
$pages->setParent(blah blah);
$innerPages = new Pages();
/* load innerpages into the nested array */
$innerPages->loadPages($pages->getId(), $pages->nested);
array_push($data, $pages);
return true;
}
}
基本上我怎么能用Propel做到这一点?我可以很容易地将父值为0的页面拉出来:
$pages = PagesQuery::create()
->filterByParent(0)
->find();
但是我需要递归地将内部页面嵌套到它返回的对象上,即使有了Propel网站上的所有优秀文档,我的努力仍然存在.
使用我的旧Pages类,如果我print_r $data,我会得到这样的东西(仅仅是使用上表的一个例子.):
Array(
[0] => Pages Object
(
[id] => 2
[page] => B
[parent] => 0
[nested] = Array(
[0] => Pages Object
(
[id] => 3
[page] => C
[parent] => 2
)
)
)
我有这个工作,但我不知道这是最好的方式.
function loadPages($parent=0, $siteId, &$arr){
$arr = PagesQuery::create()
->filterBySiteId($siteId)
->filterByParentId($parent)
->find();
foreach ($arr as $i => $v) {
$arr[$i]->nested = '';
loadPages($v->getId(), $siteId, $arr[$i]->nested);
}
}
$site->pages = '';
loadPages(0, $site->getId(), $site->pages);
我的架构没有自我关系设置,所以我刚刚在同一个表中添加了一个外键,并重新运行propel来重新创建类.我仍然不确定如何编写推进查询(为了节省空间,我已经从架构中删除了几个列).对不起,这个帖子现在开始了.
<table name="pages" PHPName="Pages">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true"/>
<column name="userId" type="integer" required="false"/>
<column name="siteId" type="integer" required="false"/>
<column name="parentId" type="integer" required="false"/>
<foreign-key foreignTable="users" PHPName="Users" refPHPName="Pages">
<reference local="userId" foreign="id"/>
</foreign-key>
<foreign-key foreignTable="sites">
<reference local="siteId" foreign="id"/>
</foreign-key>
<foreign-key foreignTable="pages">
<reference local="parentId" foreign="id"/>
</foreign-key>
</table>
解决方法:
正如您在对该问题的评论中提到的那样:嵌套集就是答案.
起初这可能听起来像解决问题的方法,但嵌套集是其他人有类似问题的结果.它是一种很好的研究和一种表示树木的流行方式.它的主要优点是能够管理可变深度树.
你提到你是Propel的新手并且切换到嵌套集会有相当多的工作,所以我冒昧地假设你之前没有使用过Propel的行为.如果是这种情况,请务必阅读文档部分关于Behaviors.
如果你现在喜欢Propel,那么你会喜欢它!
要解决您的问题:请查看NestedSet Behavior.与所有其他行为一样,可以轻松地将其添加到您的架构中.重新生成模型,您只需要对代码进行小的重构(示例将向您展示如何).
(注意:如果您有现有数据库,则需要将该父链接迁移到嵌套集结构.但这基本上是您应该关注的唯一问题.)
Using a RecursiveIterator部分提供了显示整个树的示例.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。