kappa/doctrine-mptt

修改前序遍历 doctrine 实现

dev-master / 1.0.x-dev 2015-03-03 16:33 UTC

This package is auto-updated.

Last update: 2024-09-04 19:14:44 UTC


README

Build Status

修改前序遍历 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

优势

  1. 最小化查询次数。删除需要 3 次查询(1x DELETE,2x UPDATE),创建需要 3 次查询(1x INSERT,2x UPDATE),移动项只需要 1x UPDATE 查询。此算法比其他常用方法(如经典父子方法)快得多,且更节能。
  2. 完全控制嵌套深度或分支数量

限制和警告

  1. 此软件包已在 MySQL、SQLite 和 PostgreSQL 上进行测试,并且与它们兼容
  2. 因为此软件包在执行 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 特性,该特性实现了所有必需的方法和列。

管理器

原始树结构

Original

Kappa\DoctrineMPTT\TraversableManager 通过三种方法提供所有操作。

插入项

insertItem(TraversableInterface $actual, TraversableInterface $parent = null, $refresh)

第二个参数是新父项,实际项(第一个参数)将被包含在父项下。最后一个参数是布尔值,如果设置为 true,则实体将被刷新。例如:此代码生成以下树

$parent = $this->repository->find(4);
$actual = new TraversableEntity();
// ....
$this->traversableManager->insertItem($parent, $actual);

After insert

如果父项为 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) 结果

After move predecessor

(2) 结果

After move predecessor

(3) 结果

After move predecessor

删除项

removeItem(TraversableInterface $actual)

删除项及其所有子项 例如

$actual = $this->repository->find(2);
$this->traversableManager->removeItem($actual);

After delete

查询

  1. Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetAll - 返回所有项目以进行可扩展的列表
  2. Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetParents - 返回实际项的所有父项
  3. Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetChildren - 返回实际项的所有子项
  4. Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetPrevious - 返回前一个项
  5. Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetNext - 返回下一个项
  6. Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetParent - 返回父项
  7. Kappa\DoctrineMPTT\Queries\Objects\Selectors\GetRoot - 返回树根

您可以使用 Kappa\DoctrineMPTT\Queries\SelectorsCollector 作为查询对象的简化获取器