kappa / doctrine-mptt
修改前序遍历 doctrine 实现
Requires
- kappa/doctrine: 3.0.*-dev
- nette/di: ~2.2@dev
Requires (Dev)
- doctrine/data-fixtures: ~1.0
- nette/nette: ~2.2@dev
- nette/tester: ~1.0
This package is auto-updated.
Last update: 2024-09-04 19:14:44 UTC
README
修改前序遍历 doctrine 实现。
http://www.sitepoint.com/series/storing-hierarchical-data-in-a-database/
需求
从 Composer 配置文件 中获取依赖项的完整列表
安装
安装 Kappa\DoctrineMPTT 的最佳方式是使用 Composer
$ composer require kappa/doctrine-mptt:@dev
并注册扩展
extensions: doctrine: Kappa\Doctrine\DI\DoctrineExtension doctrineMPTT: Kappa\DoctrineMPTT\DI\DoctrineMPTTExtension
优势
- 最小化查询次数。删除需要 3 次查询(1x
DELETE
,2xUPDATE
),创建需要 3 次查询(1xINSERT
,2xUPDATE
),移动项只需要 1xUPDATE
查询。此算法比其他常用方法(如经典父子方法)快得多,且更节能。 - 完全控制嵌套深度或分支数量
限制和警告
- 此软件包已在 MySQL、SQLite 和 PostgreSQL 上进行测试,并且与它们兼容
- 因为此软件包在执行
moveItem()
或insertItem()
后直接与数据库交互以最小化查询次数,所以您应该刷新已加载的实体。**注意!在调用这些方法之前必须保存所有更新,以避免冲突**。
配置
您可以设置用于列的自定义名称
doctrineMPTT: entityClass: Your\entity originalLeftName: _lft leftColumnName: lft rightColumnName: rgt depthColumnName: depth
配置可能不在配置文件中,但可以通过 Kappa\DoctrineMPTT\TraversableManager::setConfigurator
设置。
用法
该软件包提供主要的 Kappa\DoctrineMPTT\TraversableManager
,可用于所有操作。所有操作都在 Kappa\DoctrineMPTT\Entities\TraversableInterface
实例的实体上执行。
实体
您可以使用自己的实体,但您的实体必须实现 Kappa\DoctrineMPTT\Entities\TraversableInterface
接口。为了更容易实现,您可以使用 Kappa\DoctrineMPTT\Entities\Traversable
特性,该特性实现了所有必需的方法和列。
管理器
原始树结构
Kappa\DoctrineMPTT\TraversableManager
通过三种方法提供所有操作。
插入项
insertItem(TraversableInterface $actual, TraversableInterface $parent = null, $refresh)
第二个参数是新父项,实际项(第一个参数)将被包含在父项下。最后一个参数是布尔值,如果设置为 true
,则实体将被刷新。例如:此代码生成以下树
$parent = $this->repository->find(4); $actual = new TraversableEntity(); // .... $this->traversableManager->insertItem($parent, $actual);
如果父项为 null,则实际项将作为根元素的最后一个子项插入,如果根元素存在。如果不存在根元素,则实际项将作为根元素插入。
移动项
moveItem(TraversableInterface $actual, TraversableInterface $related, action, refresh)
使用此方法可以将每个项移动到新位置(作为前驱或后继)。最后一个参数是布尔值,如果设置为 true
,则实体将被刷新。例如 前驱
// (1) $actual = $this->repository->find(3); $related = $this->repository->find(2); $this->traversableManager->moveItem($actual, $related, TraversableManager::PREDECESSOR); // (1) - move actual before related // (2) $actual = $this->repository->find(3); $related = $this->repository->find(4); $this->traversableManager->moveItem($actual, $related, TraversableManager::DESCENDANT); // (2) - move actual as child of related // (3) $actual = $this->repository->find(3); $this->traversableManager->moveItem($actual, null, TraversableManager::DESCENDANT); // (3) - move actual as last child of root
(1) 结果
(2) 结果
(3) 结果
删除项
removeItem(TraversableInterface $actual)
删除项及其所有子项 例如
$actual = $this->repository->find(2); $this->traversableManager->removeItem($actual);
查询
Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetAll
- 返回所有项目以进行可扩展的列表Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetParents
- 返回实际项的所有父项Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetChildren
- 返回实际项的所有子项Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetPrevious
- 返回前一个项Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetNext
- 返回下一个项Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetParent
- 返回父项Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetRoot
- 返回树根
您可以使用 Kappa\DoctrineMPTT\Queries\SelectorsCollector
作为查询对象的简化获取器