ClosureTable
分支
- L4 支持Laravel 4
- L5.1 支持Laravel< 5.2
- L5.3 支持Laravel 5.2-5.3
- L5.4 支持Laravel 5.4
- master 适用于任何实际的Laravel版本,因此请小心
嗨,这是Laravel的数据库包。它旨在用于需要在数据库中操作分层数据的情况。该包是一个名为Closure Table的着名数据库设计模式的实现。该软件包包括用于模型和迁移的生成器。
安装
要安装软件包,请将以下内容放入composer.json中:
"require": { "franzose/closure-table": "4.*" }
app/config/app.php :
'providers' => array( // ... 'Franzose\ClosureTable\ClosureTableServiceProvider', ),
设置您的ClosureTable
创建模型和迁移
例如,让我们假设您正在处理页面。您可以使用 artisan 命令自动创建模型和迁移,而无需手动准备所有内容。打开终端并输入以下内容:
php artisan closuretable:make --entity=page
命令的所有选项:
- --namespace , -ns [可选] :类的命名空间,由设置 - entity 和 - closure 选项,有助于避免这些选项中的名称空间重复
- --entity , -e :entity class name;如果使用名称空间名称,那么默认的闭包类名称将以该名称空间
为前缀
- --entity-table , -et [可选] :实体表名称
- --closure , -c [可选] :封闭类名称
- --closure-table [可选] , -ct :封闭表名称
- --models-path , -mdl [可选] :自定义模型路径
- --migrations-path , -mgr [可选] :自定义迁移路径
- --use-innodb 和 -i [可选] :创建InnoDB迁移也是可选的。设置这将启用InnoDB引擎。
这几乎都是,伙计们! 'dummy'的东西刚刚为你创造。您需要为实体迁移添加一些字段,因为创建的“dummy”仅包含
必填id , parent_id , position 和真实深度列:
- id 是一个常规的自动增量列
- parent_id 列用于简化祖先查询的立即操作,例如简化构建整个树
- position 列被封装广泛用于实体可排序
- 真实深度 列也用于简化查询并减少查询次数
默认情况下,实体的闭包表包含以下列:
- Autoincremented identifier
- Ancestor column指向父节点
- Descendant column指向子节点
- Depth column在树中显示节点深度
它是通过闭合表格模式设计的,所以请记住,您不能删除这四列。
请记住,许多内容都是可自定义的,所以请参阅自定义以获取更多信息。
编码时间
一旦你的模型和数据库表被创建,最后,你可以开始真正的编码。在这里,我将向您展示ClosureTable的具体方法。
直接祖先(父母)
$parent = Page::find(15)->getParent();
祖先
$page = Page::find(15); $ancestors = $page->getAncestors(); $ancestors = $page->getAncestorsTree(); // Tree structure $ancestors = $page->getAncestorsWhere('position', '=', 1); $hasAncestors = $page->hasAncestors(); $ancestorsNumber = $page->countAncestors();
直系后代(孩子)
$page = Page::find(15); $children = $page->getChildren(); $hasChildren = $page->hasChildren(); $childrenNumber = $page->countChildren(); $newChild = new Page(array( 'title' => 'The title', 'excerpt' => 'The excerpt', 'content' => 'The content of a child' )); $newChild2 = new Page(array( 'title' => 'The title', 'excerpt' => 'The excerpt', 'content' => 'The content of a child' )); $page->addChild($newChild); //you can set child position $page->addChild($newChild, 5); //you can get the child $child = $page->addChild($newChild, null, true); $page->addChildren([$newChild, $newChild2]); $page->getChildAt(5); $page->getFirstChild(); $page->getLastChild(); $page->getChildrenRange(0, 2); $page->removeChild(0); $page->removeChild(0, true); //force delete $page->removeChildren(0, 3); $page->removeChildren(0, 3, true); //force delete
后代
$page = Page::find(15); $descendants = $page->getDescendants(); $descendants = $page->getDescendantsWhere('position', '=', 1); $descendantsTree = $page->getDescendantsTree(); $hasDescendants = $page->hasDescendants(); $descendantsNumber = $page->countDescendants();
邻近
$page = Page::find(15); $first = $page->getFirstSibling(); //or $page->getSiblingAt(0); $last = $page->getLastSibling(); $atpos = $page->getSiblingAt(5); $prevOne = $page->getPrevSibling(); $prevAll = $page->getPrevSiblings(); $hasPrevs = $page->hasPrevSiblings(); $prevsNumber = $page->countPrevSiblings(); $nextOne = $page->getNextSibling(); $nextAll = $page->getNextSiblings(); $hasNext = $page->hasNextSiblings(); $nextNumber = $page->countNextSiblings(); //in both directions $hasSiblings = $page->hasSiblings(); $siblingsNumber = $page->countSiblings(); $sibligns = $page->getSiblingsRange(0, 2); $page->addSibling(new Page); $page->addSibling(new Page, 3); //third position //add and get the sibling $sibling = $page->addSibling(new Page, null, true); $page->addSiblings([new Page, new Page]); $page->addSiblings([new Page, new Page], 5); //insert from fifth position
根(没有祖先的实体)
$roots = Page::getRoots(); $isRoot = Page::find(23)->isRoot(); Page::find(11)->makeRoot(0); //at the moment we always have to set a position when making node a root
整棵树
$tree = Page::getTree(); $treeByCondition = Page::getTreeWhere('position', '>=', 1);
您处理集合,因此您可以像平常一样控制其项目。 Descendants? 它们已经装好了。
$tree = Page::getTree(); $page = $tree->find(15); $children = $page->getChildren(); $child = $page->getChildAt(3); $grandchildren = $page->getChildAt(3)->getChildren(); //and so on
移动
$page = Page::find(25); $page->moveTo(0, Page::find(14)); $page->moveTo(0, 14);
删除子树
如果出于某种原因不使用外键,则可以手动删除子树。这将删除该页面及其所有后代:
$page = Page::find(34); $page->deleteSubtree(); $page->deleteSubtree(true); //with subtree ancestor $page->deleteSubtree(false, true); //without subtree ancestor and force delete
定制
您可以自定义由ClosureTableartisan 命令创建的类中的默认内容:
- Entity table name:更改受保护的$table 属性。
- Closure table name:在您的 ClosureTable(例如 PageClosure)中执行相同的操作。
- Entity's parent_id, position, and real depth column names:分别更改 getParentIdColumn()、getPositionColumn()和getRealDepthColumn()的返回值。
- Closure table's ancestor, descendant, and depth columns names:分别更改 getAncestorColumn()、getDescendantColumn()和 getDepthColumn() 的返回值。