我有一个简单的数据库表,它通过parent_id属性实现树结构。
+----+------+-----------+
| id | name | parent_id |
+----+------+-----------+
| 1 | test | null |
+----+------+-----------+
| 2 | tes2 | 1 |
+----+------+-----------+
| 3 | tes3 | 2 |
+----+------+-----------+
| 4 | tst | 2 |
+----+------+-----------+
我想获得具有树结构的PHP对象。因此,对象类别将具有属性子类别,即类别对象列表等。我希望通过Pomm的递归sql查询直接从PostgreSQL数据库中获取此对象。目标不是遍历获得的数据并在PHP中构建这样的对象。我想要直接处理PostreSQL-
至于现在,我只在第一级就得到了我想要的。所以第一级类别有子类别,即类别实体列表。但是,下一个级别(深度2)没有子类别。
到目前为止,我有:
$sql = <<<SQL
with recursive
cat as (select c.* FROM :category c where parent_id is null),
subcat as (
select c.* from :category c join cat on c.parent_id=cat.id
union all
select c.* from :category c join subcat on c.parent_id=subcat.id
)
select :projection from cat cc, subcat
where cc.id=subcat.parent_id
group by :group_fields
SQL;
$projection = $this->createProjection()
->setField('subcategories', 'array_agg(subcat)', 'public.category[]');
$sql = strtr($sql, [
':category' => $this->structure->getRelation(),
':projection' => $projection->formatFieldsWithFieldAlias('cc'),
':group_fields' => $this->createProjection()->formatFields('cc'),
]);
我的问题是,这在Pomm中是否可行,如果可行,如何实现?
您想要直接实现的并不是真正可能的,因为在Pomm中,出于性能原因,当执行查询时,迭代器将数据库游标包装在结果上。
$iterator = $this->query($sql, $array_of_parameters);
foreach ($iterator as $entity) {
$entity->getParentId();
}
每次从迭代器中提取数据时,转换器系统都会将其转换为实体。但实体不了解数据库,因此无法使用其访问器获取更多数据。
一个简单的想法是获取一个结果,其中包含作为嵌套实体的所有结果:
with recursive
cat as (
select * from test_tree tt where not exists (select parent_id from test_tree tt2 where tt2.parent_id = tt.id)
union all
select tt.*, array_agg(child) from test_tree tt join cat child on tt.id = child.parent_id group by tt.id
)
select * from cat
但不幸的是,在CTE的递归项中不可能使用聚合函数。
另一个想法是索引id上的结果,为每个parent_id提供子级,并使用Pomm迭代器可滚动来获取它们:
with
tree as (
select
tt.id,
array_agg(child) as children
from
test_tree tt
join lateral (select * from test_tree tt2 where tt2.parent_id = tt.id) child on (true) group by tt.id
)
select
idx as id,
tree.children
from
generate_series(1, (select max(id) from test_tree)) idx
left join tree on tree.id = idx
哪些输出:
┌────┬─────────────────────────────────────────┐
│ id │ children │
├────┼─────────────────────────────────────────┤
│ 1 │ {"(2,\"test 2\",1)","(3,\"test 3\",1)"} │
│ 2 │ {"(4,\"test 4\",2)","(5,\"test 5\",2)"} │
│ 3 │ {"(6,\"test 6\",3)"} │
│ 4 │ ¤ │
│ 5 │ ¤ │
│ 6 │ {"(7,\"test 7\",6)"} │
│ 7 │ ¤ │
└────┴─────────────────────────────────────────┘
(7 rows)
然后,结果集将按parent\u id so$迭代器排序-
从另一方面考虑这个问题,似乎可以创建专用的灵活实体,在内部嵌入嵌套集设计模式以在子级上递归。
在树结构的目录系统中,任何目录条目都可以是文件或子目录。 树结构的目录系统克服了两级目录系统的缺点。 现在可以将类似的文件分组到一个目录中。 每个用户都有自己的目录,并且不能进入其他用户的目录。 但是,用户有权读取根数据,但他不能写入或修改此数据。 只有系统管理员才能完全访问根目录。 在这个目录结构中搜索更有效率。 使用当前工作目录的概念。 一个文件可以通过两种类型的路径访问,无论是相对的还是绝对
好吧,我就直接说吧。我有一个使用Spring的多模块maven项目。项目结构可概括如下: 在本例中,根级pom文件将spring-boot-starter声明为父级: > 我可以分离出依赖项,以便模块1和模块2将spring-boot-starter-parent作为它们的父项,并从根pom中删除spring-boot-starter,从而释放common。 我可以将根pom作为父级删除到Comm
我在项目中有两个模块(和)运行集成测试。我希望在测试之前,我的应用程序将使用liquibase启动和滚动迁移,但由于我通过集成测试模块运行应用程序,liquibase正在寻找一个关于该模块的主文件,该文件导致了错误。因为主文件位于miom应用程序()的模块中
新加入WPF的我正尝试使用TreeView,它提供的灵活性给我留下了难以置信的印象。 到目前为止,我的每个treeview项目都实现了一个扩展器,这是显示每个项目更详细信息并让标题仅显示摘要的好方法。但是,这不适合叶项目,并且浪费了屏幕空间——我的treeview中的每个叶项目(其中有许多)显示的数据量相对较小。 我想要为叶项目实现的是水平包装,而不是垂直列表。设想显示一个网格或(stackpan
比如一辆车,在Threejs中你可以使用一个网格模型去描述车上面的一个零件,多个零件就需要多个网格模型表示,这些网格模型之间就会构成父子或兄弟关系,从而形成一个层级结构。在机械、建筑相关的Web3D应用中,通常会用到层级模型的知识,一个层级模型就是一本书的目录一样。 本章主要目的是帮助你建立Threejs层级模型的概念,通过Threejs的组对象Group可以组织各个模型,构成一个层级结构。学习本